Issue
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.
Solution
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)
)
);
}
Answered By - csalmhof