2013-10-30 4 views
6

Voglio scrivere test di unità (junit4) per il mio plug-in maven. Tutti gli esempi che ho trovato l'uso "AbstractMojoTestCase" (junit3 :-() Per sbarazzarsi di questo ho ottenuto answer here Ma il problema è come ottenere Mojos istanziato:..Come simulare l'ambiente di plugin maven eo la configurazione di progetto

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

Ciò significa che ho bisogno di un pom per tutti i casi di test - il pom è il test dati di input.Ma c'è un modo per deridere (io userei Mockito) il modello di progetto un po 'come? Potrebbe essere lookupMojo(String groupId, String artifactId, String version, String goal, PlexusConfiguration pluginConfiguration) essere un buon punto di partenza? In questo caso vorrei prendere in giro "PlexusConfiguration", ma quali metodi ? Alcuni maven-plugin testing doku utilizzano classi come "MavenProjectStub" .Ma non riesco a ottenere un'immagine coerente di come viene creato un mojo e di quali input si parla sulla creazione.

Una soluzione perfetta sarebbe se solo potessi

@inject 
MyMojo testObject; 

e basta prendere in giro tutte le cose ha bisogno per farlo funzionare (ho bisogno primario parametri @)

+0

ci sono novità su questo? questo sarebbe MOLTO utile – pigiuz

+0

no nessuna novità qui, ma probabilmente la votazione della domanda sarebbe d'aiuto ?! :-) – dermoritz

risposta

5

Sulla base della mia esperienza di scrittura Maven plug-in, ci ci sono due livelli di test di un plugin: tramite unit test (usando mock) e tramite test di integrazione (usando il plugin di maven-invoker).

Per i test di integrazione, l'archetipo Maven per nuovi plugin Maven già fornire un buon esempio fuori dalla scatola, appena eseguire il seguente e dare un'occhiata a questo:

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

Per impostazione predefinita si otterrà l'integrazione prova in un profilo per iniziare. Sarà anche disponibile un esempio di progetto maven (sotto src \ it \ simple-it \ pom.xml) che può eseguire gli obiettivi del plugin. Quello che suggerisco è anche quello di far rispettare il risultato del test di integrazione tramite vincoli aggiuntivi in ​​quel pom.xml. Ad esempio: puoi aggiungere la regola Maven Enforcer Plugin per verificare i file creati, se questo ha senso per il tuo plug-in.

Per rispondere più specificamente alla tua domanda su come scrivere unit test per Maven personalizzati plugin, questo è l'approccio che sto usando:

  • JUnit + Mockito.
  • Test case eseguito con @RunWith (MockitoJUnitRunner.class)
  • Mock Classi Maven specifici (MavenProject, Log, Build, DependencyNode, ecc.) Che utilizzano @Mock annotazioni
  • avviare e collegano gli oggetti finti in un metodo @Before (tipicamente setup() metodo)
  • prova il plugin :)

A titolo di esempio, si potrebbe avere il seguente deriso oggetti come variabile di classe della vostra unit test:

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

Poi, nel tuo metodo @Before è necessario aggiungere un grande di codice di colla come segue:

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

Per esempio, io uso per scrivere qualche Enforcer personalizzato Plugin regole, quindi ho bisogno di

@Mock 
private EnforcerRuleHelper helper; 

E nel metodo @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); 

Come tale, sarà facile da usare questi simulare oggetti nei test. Per esempio, un must have primo test manichino è quello di testare contro una build vuota come segue (in basso prova di una regola Enforcer su ordinazione):

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

Se hai bisogno di testare contro le dipendenze di build, per esempio, potrebbe finire per scrivere metodi di utilità come segue:

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

al fine di creare facilmente le dipendenze nel grafo delle dipendenze di creazione, come segue:

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

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

NOTA: yo Puoi migliorare il metodo di utilità se hai bisogno di ulteriori dettagli (come l'ambito o il classificatore per una dipendenza).

Se hai bisogno anche alla configurazione finta di un plugin, perché è necessario eseguire la scansione di plugin esistenti e la loro configurazione, per esempio, si può fare come segue:

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

io ovviamente non coprire tutto il casi possibili, ma sono sicuro che hai una comprensione dell'approccio e dell'uso. Spero che sia d'aiuto.