【问题标题】:JUnit 5 and Arguments.of() with functionsJUnit 5 和 Arguments.of() 函数
【发布时间】:2020-10-05 06:54:57
【问题描述】:

编写 JUnit 5 参数化测试并需要使用 Arguments.of() 将函数传递给测试,但有 2 个编译错误我不知道如何修复。任何帮助将不胜感激。

  1. Arguments 类型中的(Object...) 方法不适用于参数(boolean, String::length)
  2. 此表达式的目标类型必须是函数式接口

public static Stream<Arguments> some() {
    return Stream.of(Arguments.of(true, String::length));
}

@ParameterizedTest
@MethodSource
public <T> void some(final T input, final Function<String, Integer> length) {
}

以下内容按预期工作。

public void sample() {
    some(true, String::length);
}

【问题讨论】:

    标签: junit5 parameterized


    【解决方案1】:

    函数需要封装在一个类中。

    public static class P {
    
        private final Function<String, Integer> mFunction;
    
        public P(final Function<String, Integer> function) {
            mFunction = function;
        }
    
        public Function<String, Integer> function() {
            return mFunction;
        }
    }
    
    public static Stream<Arguments> some() {
        return Stream.of(Arguments.of(3, "abc", new P(String::length)));
    }
    
    @ParameterizedTest
    @MethodSource
    public <T> void some(final int expect, final String input, final P p) {
        assertEquals(expect, p.function().apply(input));
    }
    

    【讨论】:

      【解决方案2】:

      将参数包装在辅助方法中
      类似于“将其包装在一个类中”的答案,但侵入性可能较小,是使用辅助方法将功能接口作为java.lang.Object 传递。

      例如,此参数化测试中的第一个原始方法引用 Math::ciel

      @ParameterizedTest
      @MethodSource("testCases")
      void shouldExerciseMethod(Function<Double, Double> method, Double expected) {
          assertEquals(expected, method.apply(1.5d), 1.0E-8d);
      }
          
      static Stream<Arguments> testCases() {
          return Stream.of(Arguments.of(Math::ceil, 2.0d),
                           Arguments.of(Math::floor, 1.0d));
      }
      

      导致此编译错误:

      java: method of in interface org.junit.jupiter.params.provider.Arguments cannot be applied to given types;
        required: java.lang.Object[]
        found: Math::ceil,double
        reason: varargs mismatch; java.lang.Object is not a functional interface
      

      您可以通过辅助方法传递参数来解决:

      static <T, U> Arguments args(Function<T, U> method, U expected) {
          return Arguments.of(method, expected);
      }
      

      所以:

      static Stream<Arguments> testCases() {
          return Stream.of(args(Math::ceil, 2.0d), 
                           args(Math::floor, 1.0d));
      }
      

      我尝试使用varargs 使成语更通用,但由于同一错误的变化而失败,所以每当我需要另一个签名时,我最终都会重载它。

      【讨论】:

        猜你喜欢
        • 2020-07-29
        • 1970-01-01
        • 2017-09-02
        • 1970-01-01
        • 1970-01-01
        • 2017-06-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多