2013-10-30 36 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); 

我顯然不會覆蓋所有的可能的情況下,但我相信你瞭解方法和用法。希望能幫助到你。