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
which is generated by the Maven Archetype Plugin, i.e.:
mvn archetype:create \
-DgroupId=org.apache.maven.plugin.my \
-DartifactId=maven-my-plugin \
-DarchetypeArtifactId=maven-archetype-mojo
The generated structure should be:
maven-my-plugin
|- pom.xml
+- src/
+- main/
+- java/
+- org/
+- apache/
+- maven/
+- plugin/
+- my/
|- MyMojo.java
Recipe
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>
...
</dependencies>
...
</project>
Create a MyMojoTest
Create a MyMojoTest
(by convention) class in src/test/java/org/apache/maven/plugin/my
directory. This class should extend AbstractMojoTestCase
from maven-plugin-testing-harness
.
import org.apache.maven.plugin.testing.AbstractMojoTestCase;
public class MyMojoTest
extends AbstractMojoTestCase
{
/** {@inheritDoc} */
protected void setUp()
throws Exception
{
// required
super.setUp();
...
}
/** {@inheritDoc} */
protected void tearDown()
throws Exception
{
// required
super.tearDown();
...
}
/**
* @throws Exception if any
*/
public void testSomething()
throws Exception
{
File pom = getTestFile( "src/test/resources/unit/project-to-test/pom.xml" );
assertNotNull( pom );
assertTrue( pom.exists() );
MyMojo myMojo = (MyMojo) lookupMojo( "touch", pom );
assertNotNull( myMojo );
myMojo.execute();
...
}
}
In this case, testSomething()
will test MyMojo
against a Maven project called project-to-test
.
Note: By convention, projects for unit testing your should be in the test resources directory.
Alternatively to extending AbstractMojoTestCase
and when using Junit-4.10 ff., you may use a MojoRule
, which just embeds an AbstractMojoTestCase
.
When you do not need the functionality in every test method, you may use the @WithoutMojo
annotation to skip rule executions.
import org.apache.maven.plugin.testing.MojoRule;
import org.apache.maven.plugin.testing.WithoutMojo;
import org.junit.Rule;
import static org.junit.Assert.*;
import org.junit.Test;
public class MyMojoTest
{
@Rule
public MojoRule rule = new MojoRule()
{
@Override
protected void before() throws Throwable
{
}
@Override
protected void after()
{
}
};
/**
* @throws Exception if any
*/
@Test
public void testSomething()
throws Exception
{
File pom = rule.getTestFile( "src/test/resources/unit/project-to-test/pom.xml" );
assertNotNull( pom );
assertTrue( pom.exists() );
MyMojo myMojo = (MyMojo) rule.lookupMojo( "touch", pom );
assertNotNull( myMojo );
myMojo.execute();
...
}
/** Do not need the MojoRule. */
@WithoutMojo
@Test
public void testSomethingWhichDoesNotNeedTheMojoAndProbablyShouldBeExtractedIntoANewClassOfItsOwn()
{
...
}
}
Configuring project-to-test
pom
Just create a pom as usual. The names for groupId and artifactId don't really matter since this project will not be deployed.
<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 http://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>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-my-plugin</artifactId>
<configuration>
<!-- Specify the MyMojo parameter -->
<outputDirectory>target/test-harness/project-to-test</outputDirectory>
</configuration>
</plugin>
</plugins>
</build>
</project>
Execute test
As usual, just call:
mvn test