2013-10-30 32 views
6

我想为我的maven-plugin编写单元测试(junit4)。所有的例子我发现使用“AbstractMojoTestCase”(junit3 :-()为了摆脱这个我得到了answer here但问题是Mojos是如何被实例化:。如何模拟maven插件环境和或项目配置

MyMojo myMojo = (MyMojo) lookupMojo("touch", pom); 

这意味着我需要一个POM为每个测试用例 - pom是测试输入数据,但有没有办法模拟(我会使用Mockito)项目模型一些如何? 可能lookupMojo(String groupId, String artifactId, String version, String goal, PlexusConfiguration pluginConfiguration)是一个很好的起点?在这种情况下,我会模拟“PlexusConfiguration”,但是什么方法? 一些maven-plugin testing doku使用了类似“MavenProjectStub”的类,但是我无法获得关于如何创建魔咒的一致画面,以及它在创建时谈论什么界面

一个完美的解决方案是,如果我可以只

@inject 
MyMojo testObject; 

,只是嘲笑它需要得到它的工作(主要我需要@参数)根据我的经验写Maven插件

+0

有关这方面的消息吗?这将是非常有用的 – pigiuz

+0

不,这里没有消息,但可能投票的问题会有帮助?! :-) – dermoritz

回答

5

的所有的东西,有是测试插件的两个级别:通过单元测试(使用mocks)和通过集成测试(使用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插件规则来检查创建的文件,如果这对您的插件有意义。

为了更具体地回答了关于如何编写自定义Maven插件单元测试你的问题,这是我使用的方法:

  • 的JUnit +的Mockito。
  • 使用@RunWith(MockitoJUnitRunner.class)运行测试用例
  • 模拟Maven特定类(MavenProject,Log,Build,DependencyNode等)使用)@Mock注释
  • 启动,并在@Before方法链接您的模拟对象(通常设置()方法)
  • 测试你的插件:)

举个例子,你可能有以下嘲笑对象作为单元测试的类变量:

@Mock 
private MavenProject project; 
@Mock 
private Log log; 
@Mock 
Build build; 

然后,在你的@Before方法,你需要添加一个大的胶水代码如下:

Mockito.when(this.project.getBuild()).thenReturn(this.build); 

举例来说,我用它来编写一些自定义的强制实施插件规则,因此我需要

@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); 
    // mock 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(); // no need to mock it 
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); 

我显然不会覆盖所有的可能的情况下,但我相信你了解方法和用法。希望能帮助到你。