I am trying to pass test arguments to JUnit 5 that include Java's Function<T, R>
interface type as shown in the following code snippet. I am getting a "Target type of a lambda conversion must be an interface" error because JUnit 5's Arguments
type uses an Object array to store the parameters.
@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";
}
If I generate a stream that only uses the Function<T, R>
interface type the test compiles and runs fine.
@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";
}
Obviously the actual code is a bit more complex. The reason why I want to pass functions instead of test data objects is because we call different methods with a different set of parameters. It is just a lot tidier to encapsulate that in helper methods.
CodePudding user response:
You need to tell the compiler which sort of lambda you intend to implent.
So you need to cast your lambda to a Function<String, String>
like this:
private static Stream<Arguments> generateArguments() {
return Stream.of(
Arguments.of(
"Return 'expected' if argument is 'input'",
(Function<String, String>) JUnitFeatureTest::generateStringFromInput
)
);
}
or this
private static Stream<Arguments> generateArguments() {
return Stream.of(
Arguments.of(
"Return 'expected' if argument is 'input'",
(Function<String, String>) input -> generateStringFromInput(input)
)
);
}