Skip to content

MojoExtension's parameter resolving conflicts with other JUnit parameter resolvers #244

@elmuerte

Description

@elmuerte

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

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions