2013-10-30 3 views
6

Ich möchte Komponententests (Junit4) für meine Maven-Plugin schreiben. Alle Beispiele gefunden i use „AbstractMojoTestCase“ (junit3 :-() Um dieses i answer here bekam loswerden Aber das Problem ist, wie Mojos instanziiert erhalten:..Wie maven Plugin-Umgebung und oder Projektkonfiguration zu spotten

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

Das heißt, ich ein pom für jeden Testfall brauchen - Die Pom ist die Test-Eingabedaten. Aber gibt es eine Möglichkeit zu Mockito (ich würde Mockito verwenden) das Projektmodell einige wie? Könnte lookupMojo(String groupId, String artifactId, String version, String goal, PlexusConfiguration pluginConfiguration) ein guter Ausgangspunkt sein? In diesem Fall würde ich "PlexusConfiguration" spotten, aber welche Methoden ? Einige maven-plugin testing doku verwendet Klassen wie "MavenProjectStub". Aber ich kann nicht ein konsistentes Bild davon erhalten, wie ein Mojo erstellt wird und mit welchen Schnittstellen es bei der Erstellung spricht.

es

Eine perfekte Lösung wäre, wenn ich

konnte diese
@inject 
MyMojo testObject; 

und nur das ganze Zeug verspotten sie es bekommen müssen arbeiten (primäre i @Parameter müssen)

+0

irgendwelche Nachrichten zu diesem Thema? das wäre sehr nützlich – pigiuz

+0

nein keine Nachrichten hier, aber wahrscheinlich Abstimmung Frage würde helfen ?! :-) – dermoritz

Antwort

5

Aufgrund meiner Erfahrung Schreiben Maven Plugin, Es gibt zwei Ebenen zum Testen eines Plugins: über Unit-Test (mit Mocks) und über Integrationstests (mit dem Maven-Invoker-Plugin).

Für die Integrationstests bieten die Maven Urbild für neue Maven Plugins bereits ein gutes Beispiel aus der Box führen Sie einfach die folgenden und einen Blick auf sie haben:

mvn archetype:generate \ 
    -DgroupId=sample.plugin \ 
    -DartifactId=hello-maven-plugin \ 
    -DarchetypeGroupId=org.apache.maven.archetypes \ 
    -DarchetypeArtifactId=maven-archetype-plugin 

standardmäßig Sie die Integration bekommen Tests in einem Profil, um damit zu beginnen. Ein Beispiel Maven-Projekt wird ebenfalls verfügbar sein (unter src \ it \ simple-it \ pom.xml), die Ihre Plugin-Ziele ausführen kann. Ich schlage auch vor, das Ergebnis Ihres Integrationstests über zusätzliche Einschränkungen in dieser pom.xml zu erzwingen. Zum Beispiel: Sie können die Maven Enforcer Plugin-Regel hinzufügen, um gegen erstellte Dateien zu prüfen, wenn dies für Ihr Plugin sinnvoll ist.

genauer auf Ihre Frage zu beantworten, wie Unit-Tests für benutzerdefinierte Maven Plugins zu schreiben, das ist der Ansatz, den ich bin mit:

  • JUnit + Mockito.
  • Testfall mit @RunWith (MockitoJUnitRunner.class)
  • Mock Maven spezifische Klassen (MavenProject, Log, Build, DependencyNode usw.)) Mit @Mock Anmerkungen
  • initiieren und verknüpfen Sie Ihre Mock-Objekte in einem @Before Verfahren (typischerweise setUp() -Methode)
  • Testen Sie Ihr Plugin :)

Als Beispiel könnten Sie die folgenden verspottet Objekte als Klassenvariable des Unit-Test:

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

in Ihrem @Before Methode Dann müssen Sie wie folgt einen großen Klebstoff Code hinzuzufügen:

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

Zum Beispiel verwende ich einige benutzerdefinierte Enforcer Plugin Regeln zu schreiben, daher muss ich

@Mock 
private EnforcerRuleHelper helper; 

Und in der @Before Methode:

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); 

Als solches wird es einfach sein, diese zu verwenden Mache Objekte in deine Tests ein. Zum Beispiel muss ein ersten Dummy-Test haben, ist es gegen einen leeren Build zu testen, wie folgend (unter einer benutzerdefinierten Enforcer Regel Prüfung):

@Test 
public void testEmptyBuild() throws Exception { 
    try { 
     this.rule.execute(this.helper); 
    } catch (EnforcerRuleException e) { 
     Assert.fail("Rule should not fail"); 
    } 
} 

Wenn Sie gegen Abhängigkeiten von Build testen müssen, zum Beispiel, Sie am Ende vielleicht Utility-Methoden wie folgt zu schreiben:

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; 
} 

um wie folgt auf einfache Weise Abhängigkeiten in die Abhängigkeitsgraphen des Builds zu erstellen:

List<DependencyNode> nodes = new ArrayList<DependencyNode>(); 
nodes.add(generateNode("junit", "junit", "4.12")); 

Mockito.when(node.getChildren()).thenReturn(nodes); 

HINWEIS: yo Sie können die Utility-Methode verbessern, wenn Sie weitere Details benötigen (wie zum Beispiel Scope oder Classifier für eine Abhängigkeit).

Wenn Sie auch zu mock Konfiguration eines Plugins benötigen, weil Sie vorhandene Plugins und deren Konfiguration scannen müssen, zum Beispiel, können Sie es tun, wie folgend:

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); 

werde ich natürlich alles nicht decken die mögliche Fälle, aber ich bin mir sicher, dass Sie Verständnis für den Ansatz und die Verwendung haben. Ich hoffe es hilft.

Verwandte Themen