I'm writing some jUnit5 extensions to make it easier to test some code. The extension has these annotations:
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Test
@ExtendWith({CustomJunit5Extension.class})
public @interface MyAnnotation {
String jsonFile;
Class<?> converter;
}
// test case
class Test {
@MyAnnotation(converter = MyClass.class)
void someTest();
}
// Some class which contains a converter method annotated with @JsonConverterMethod
public class MyClass {
@JsonConverterMethod
public static Car converter(String jsonLine);
}
// jUnit5 extension
public class CustomJunit5Extension implements ParameterResolver, AfterEachCallback, AfterAllCallback {
// ultra simplified version
public Object resolveParameter(ParameterContext pctx, ExtensionContext ectx) throws ParameterResolutionException {
final MyAnnotation annotation = getAnnotation(pctx, ectx);
final Method converterMethod = getMethodByAnnotation(annotation.converter(), JsonConverterMethod.class);
@SuppressWarnings({"unchecked"})
final var converter = needs to become a
direct reference to MyClass::converter
without hardcoding it, because you can
have other classes providing different
jsonString to Object converters;
final JsonCandleProvider provider = new JsonCandleProvider(resource, converter);
return provider;
}
}
Hence the question - how to convert a Method
reference into a Lambda
reference so I could pass it to the MyJsonProvider
? Or how would you achieve a similar result in another way maybe?
CodePudding user response:
The method parameter needs to be a Functional interface of the type of the method reference.
MyMethod(() -> "Hello, World!");
Supplier<String> supplier = () -> "Hello, World!";
MyMethod(supplier);
MyMethod(supplier::get);
MyMethod2(supplier.get());
public static void MyMethod(Supplier<String> sup) {
System.out.println(sup.get());
}
public static void MyMethod2(String value) {
System.out.println(value);
}
prints
Hello, World!
Hello, World!
Hello, World!
Hello, World!