Function<T, R> 作为 Junit 5 中的附加参数

Function<T, R> as additional argument in Junit 5

我正在尝试将测试参数传递给 JUnit 5,其中包括 Java 的 Function<T, R> 接口类型,如以下代码片段所示。我收到“lambda 转换的目标类型必须是接口”错误,因为 JUnit 5 的 Arguments 类型使用对象数组来存储参数。

  @ParameterizedTest(name = "Test description: {0}")
  @MethodSource("generateArguments")
  void passFunctionAsAnArgumentTest(final String description, final Function<String, String> testMethod) {

    // Fetch initial preactivation value.
    final String result = testMethod.apply("input");
    assertThat(result, is("expected"));
  }

  private static Stream<Arguments> generateArguments() {

    return Stream.of(
        // Error: "Target type of a lambda conversion must be an interface".
        Arguments.of("Return 'expected' if argument is 'input'", (String input) -> generateStringFromInput(input))
    );
  }

  private static String generateStringFromInput(final String input) {

    return input.equals("input") ? "expected" : "wrong";
  }

如果我生成一个 使用 Function<T, R> 接口类型的流,测试编译并运行正常。

  @ParameterizedTest(name = "No test description :(")
  @MethodSource("generateStream")
  void passFunctionAsAnArgumentTest(final Function<String, String> testMethod) {

    // Fetch initial preactivation value.
    final String result = testMethod.apply("input");
    assertThat(result, is("expected"));
  }

  private static Stream<Function<String, String>> generateStream() {

    return Stream.of(
        JUnitFeatureTest::generateStringFromInput
    );
  }

  private static String generateStringFromInput(final String input) {

    return input.equals("input") ? "expected" : "wrong";
  }

显然实际代码要复杂一些。我想传递函数而不是测试数据对象的原因是因为我们使用不同的参数集调用不同的方法。将其封装在辅助方法中会更加整洁。

您需要告诉编译器您打算实现哪种 lambda。
所以你需要像这样将你的 lambda 转换为 Function<String, String>

private static Stream<Arguments> generateArguments() {
  return Stream.of(
      Arguments.of(
          "Return 'expected' if argument is 'input'",
          (Function<String, String>) JUnitFeatureTest::generateStringFromInput
      )
  );
}

或这个

private static Stream<Arguments> generateArguments() {
  return Stream.of(
      Arguments.of(
          "Return 'expected' if argument is 'input'", 
          (Function<String, String>) input -> generateStringFromInput(input)
      )
  );
}