Open sbrannen opened 3 weeks ago
Thanks for reporting, this is on our short-term plan and we will look into it. MethodSource
seems to be computed at run time and needs extra metadata.
Our future implementation of the JUnit feature will have to register this metadata based on the test annotations.
Hi @vjovanov,
MethodSource
seems to be computed at run time and needs extra metadata.
I apologize: my use of @MethodSource
to demonstrate the larger issue was perhaps a bit misleading.
NBT already has specific support for registering reflection metadata for fully-qualified method names configured via @MethodSource
, which can be seen here:
If the method name is not fully-qualified, that simply logs a debug message:
debug("Skipping method reference as it originates in the same class as the test: %s", methodName);
That "same class" part actually applies to the test class hierarchy; however, it should apply to the entire type hierarchy.
Hence, the following passes both on the JVM and within a native image, but my original example with class DemoTests implements TestInterface
does not pass within a native image.
class BaseTests {
static List<String> names() {
return List.of("Sarah", "Susan");
}
}
class DemoTests extends BaseTests {
@ParameterizedTest
@MethodSource("names")
void test(String name) {
assertEquals(5, name.length());
assertTrue(name.startsWith("S"));
}
}
The larger issue is that "test interfaces" are ignored in JUnitPlatformFeature
. This means that any use case relying on reflection for fields, methods, etc. from test interfaces will not work without custom metadata configuration.
See also: Test Interfaces and Default Methods in the JUnit 5 User Guide.
Our future implementation of the JUnit feature will have to register this metadata based on the test annotations.
As I mentioned above, that is already covered by the JupiterConfigProvider
.
The fix for this issue should likely be as simple as modifying the registerTestClassForReflection()
method in JUnitPlatformFeature
so that it recursively processes the entire type hierarchy (including implemented interfaces) for the test class.
If you need any further clarification, just let me know.
Thanks,
Sam
Overview
Given the following interface:
... and the following test class:
...
DemoTests
passes on the JVM but fails within a native image as follows.However, if
TestInterface
were a class thatDemoTests
extended the test would then pass.The reason is that the
JUnitPlatformFeature
currently invokesregisterAllClassMembersForReflection()
for all classes with the test class hierarchy, but that recursive algorithm ignores implemented interfaces.https://github.com/graalvm/native-build-tools/blob/979e9ecfcc8d2c4e35808022b3c6724212bc4417/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/JUnitPlatformFeature.java#L150-L158
The
registerTestClassForReflection()
method inJUnitPlatformFeature
should therefore be revised to process implemented interfaces (and super-interfaces) at each level of the class hierarchy.Related Issues
51
54
638