Cookbook: How To Use Maven Plugin Testing Harness?
This guide is intended as a reference for those developing Maven plugins, with self-contained references and solutions for common testing cases.
Prerequisites
We assume that you have already created a plugin. In this cookbook, we make reference to MyMojo in maven-my-plugin.
You cane reference the Guide to Developing Java Plugins to create your first plugin.
Testing Maven Plugin
Add maven-plugin-testing-harness dependency
As usual, just add maven-plugin-testing-harness as following in your POM. Be sure to specify test scope.
<project>
...
<dependencies>
<dependency>
<groupId>org.apache.maven.plugin-testing</groupId>
<artifactId>maven-plugin-testing-harness</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
...
</dependencies>
...
</project>
Create a MyMojoTest
Create a MyMojoTest (by convention) class in src/test/java/org/example/maven/plugin/my directory.
import javax.inject.Inject;
import org.apache.maven.api.plugin.testing.Basedir;
import org.apache.maven.api.plugin.testing.InjectMojo;
import org.apache.maven.api.plugin.testing.MojoParameter;
import org.apache.maven.api.plugin.testing.MojoTest;
import org.apache.maven.execution.MavenSession;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@MojoTest
class MyMojoTest {
@Inject
private MavenSession session;
// optional setup before each test
@BeforeEach
void setUp() {
// properties added to the Maven session can by used in the plugin configuration
session.getUserProperties().setProperty("someProperty", "someValue");
}
@Test
@InjectMojo(goal = "touch", pom = "src/test/resources/unit/project-to-test/pom.xml")
public void testSomething(MyMojo myMojo) throws Exception {
myMojo.execute();
...
}
@Test
// you can use @Basedir pointing to test classpath resource
@Basedir("/unit/project-to-test")
// if you not provide 'pom' parameter, it will look for 'pom.xml' in basedir
@InjectMojo(goal = "touch", pom = "another-pom.xml")
public void testSomething2(MyMojo myMojo) throws Exception {
myMojo.execute();
...
}
@Test
@InjectMojo(goal = "touch")
// you can provide simple parameters directly in the test method, without using a POM file
@MojoParameter(name = "parameter1Name", value = "parameter1Value")
@MojoParameter(name = "parameter2Name", value = "parameter2Value")
public void testSomething3(MyMojo myMojo) throws Exception {
myMojo.execute();
...
}
}
Note: By convention, projects for unit testing your should be in the test resources directory.
Configuring project-to-test POM
Just create a POM as usual. Only plugin configuration is processed by the testing harness. All other parts of the POM are ignored.
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache.maven.plugin.my.unit</groupId>
<artifactId>project-to-test</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Test MyMojo</name>
<build>
<plugins>
<plugin>
<artifactId>maven-my-plugin</artifactId>
<configuration>
<!-- Specify the MyMojo parameter -->
<outputDirectory>${basedir}/target/test-output</outputDirectory>
<complexParameter>
<param1>value1</param1>
<!-- property set in BeforeEach method -->
<param2>${someProperty}</param2>
</complexParameter>
</configuration>
</plugin>
</plugins>
</build>
</project>
Execute test
As usual, just call:
mvn test



