-
Notifications
You must be signed in to change notification settings - Fork 40
Description
Affected version
3.4.0
Bug description
MojoExtension/MojoTest cannot be used with any other JUnit extension which also provides parameter resolving. MojoExtension's supportsParameter is too broad as it will match any parameter if the method has an InjectMojo annotation.
The following example will fail
@ExtendWith({MojoExtension.class, WireMockExtension.class})
class FindingsMojoIntegrationTest {
@Test
@InjectMojo(
goal = "findings",
pom = "src/test/resources/projects/run/pom.xml")
void someTest(FindingsMojo findingsMojo, WireMockRuntimeInfo wmri) {
}
}JUnit will throw the exception
org.junit.jupiter.api.extension.ParameterResolutionException: Discovered multiple competing ParameterResolvers for parameter [com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo arg1] in method [void io.github.pmckeown.dependencytrack.finding.FindingsMojoIntegrationTest.setUp(io.github.pmckeown.dependencytrack.finding.FindingsMojo,com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo)]: org.apache.maven.api.plugin.testing.MojoExtension@106802ea, com.github.tomakehurst.wiremock.junit5.WireMockExtension@785ef70f
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
This is due to the following code
Lines 146 to 150 in 3d28d1e
| public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) | |
| throws ParameterResolutionException { | |
| return parameterContext.isAnnotated(InjectMojo.class) | |
| || parameterContext.getDeclaringExecutable().isAnnotationPresent(InjectMojo.class); | |
| } |
parameterContext.isAnnotated(InjectMojo.class) would always return false as InjectMojo can only be used on a method, and not a parameter. Then it it will check if the method contains the InjectMojo annotation without checking if the affecting parameter is even a subclass of Mojo. This would result in the extension to assign the resolved Mojo to every parameter (which JUnit will also reject due to type mismatches.)
So the the supportsParameter implementation needs to be fixed to also include Mojo.class.isAssignableFrom(parameterContext.getParameter().getType()).
Further more, it would be nice if InjectMojo and MojoParameter annotations could also be used on the parameter itself, as the code also takes that into account.