基于我编写Maven插件的经验,有两个级别可以对插件进行测试:通过单元测试(使用mock)和通过集成测试(使用maven-invoker-plugin)。
对于集成测试,Maven新插件的maven原型已经提供了一个很好的示例,只需执行以下命令并查看即可:
mvn archetype:generate \
-DgroupId=sample.plugin \
-DartifactId=hello-maven-plugin \
-DarchetypeGroupId=org.apache.maven.archetypes \
-DarchetypeArtifactId=maven-archetype-plugin
默认情况下,您将获得一个包含集成测试的配置文件来开始。还将提供一个示例Maven项目(位于src\it\simple-it\pom.xml下),可以执行您的插件目标。我建议在pom.xml中通过附加约束来强制执行您的集成测试结果。例如:如果对您的插件有意义,可以添加Maven Enforcer Plugin规则以检查创建的文件。
更具体地回答关于如何为自定义Maven插件编写单元测试的问题,以下是我使用的方法:
- JUnit + Mockito。
- 使用@RunWith(MockitoJUnitRunner.class)运行测试用例
- 使用@Mock注释模拟Maven特定类(MavenProject、Log、Build、DependencyNode等)
- 在@Before方法中初始化和链接您的模拟对象(通常是setUp()方法)
- 测试您的插件 :)
例如,您可能拥有以下模拟对象作为单元测试的类变量:
@Mock
private MavenProject project;
@Mock
private Log log;
@Mock
Build build;
然后,在你的@Before方法中,你需要添加以下的一些粘合代码:
Mockito.when(this.project.getBuild()).thenReturn(this.build)
例如,我曾经编写一些自定义的Enforcer插件规则,因此我需要...
@Mock
private EnforcerRuleHelper helper;
在@Before方法中:
Mockito.when(this.helper.evaluate("${project}")).thenReturn(this.project);
Mockito.when(this.helper.getLog()).thenReturn(this.log);
Mockito.when(this.project.getBuild()).thenReturn(this.build);
Mockito.when(this.helper.getComponent(DependencyGraphBuilder.class)).thenReturn(this.graphBuilder);
Mockito.when(this.graphBuilder.buildDependencyGraph(this.project, null)).thenReturn(this.node);
因此,将这些模拟对象用于测试将变得非常容易。例如,一个必备的首个虚拟测试是对空构建进行测试,如下所示(下面是针对自定义执行程序规则的测试):
@Test
public void testEmptyBuild() throws Exception {
try {
this.rule.execute(this.helper);
} catch (EnforcerRuleException e) {
Assert.fail("Rule should not fail");
}
}
如果您需要测试构建的依赖关系,您可能需要编写以下实用方法:
private static DependencyNode generateNode(String groupId, String artifactId, String version) {
DependencyNode node = Mockito.mock(DependencyNode.class);
Artifact artifact = Mockito.mock(Artifact.class);
Mockito.when(node.getArtifact()).thenReturn(artifact);
Mockito.when(artifact.getGroupId()).thenReturn(groupId);
Mockito.when(artifact.getArtifactId()).thenReturn(artifactId);
Mockito.when(artifact.getVersion()).thenReturn(version);
return node;
}
为了能够轻松地在构建的依赖图中创建依赖关系,可以按照以下方式操作:
List<DependencyNode> nodes = new ArrayList<DependencyNode>();
nodes.add(generateNode("junit", "junit", "4.12"));
Mockito.when(node.getChildren()).thenReturn(nodes);
注意:如果你需要进一步了解一个依赖项的作用域或分类器等详细信息,可以改进该实用方法。
如果你还需要模拟插件的配置,因为你需要扫描现有插件及其配置,例如,可以按照以下方式进行:
List<Plugin> plugins = new ArrayList<Plugin>();
Plugin p = new Plugin();
p.setArtifactId("maven-surefire-plugin");
Xpp3Dom conf = new Xpp3Dom("configuration");
Xpp3Dom skip = new Xpp3Dom("skip");
skip.setValue("true");
conf.addChild(skip);
p.setConfiguration(conf);
plugins.add(p);
Mockito.when(this.build.getPlugins()).thenReturn(plugins);
我显然不会涵盖所有可能的情况,但我相信你已经了解了方法和用法。希望这有所帮助。