2
\$\begingroup\$

I am writing an extension to a maven mojo (spring-cloud-skipper-maven-plugin) and I am now writing tests that interact with a skipper server.

However, getting the maven-plugin-testing-harness to work was a pain and meant I had to include the dependency org.eclipse.sisu.plexus.

In the end, it also meant I had to inject some fields manually using reflection because spring auto wiring was failing.

This is working perfectly now but it can definitely be improved with some tips about what should be fixed.

package io.switchbit;

import org.apache.maven.model.Model;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.testing.AbstractMojoTestCase;
import org.apache.maven.project.MavenProject;
import org.junit.Before;
import org.junit.Test;

import java.io.File;
import java.io.FileReader;
import java.lang.reflect.Field;


public class AUnitTest
        extends AbstractMojoTestCase
{
    private String SKIPPER_SERVER_URI = "http://SERVER:7577/api";

    AbstractMojo step1SkipperPackage;
    AbstractMojo step2SkipperUpload;
    AbstractMojo step3SkipperInstall;
    AbstractMojo step4SkipperDelete;

    /**
     * @see junit.framework.TestCase#setUp()
     */
    @Before
    protected void setUp() throws Exception
    {
        // required for step1SkipperPackage lookups to work
        super.setUp();

        File testPom = new File( getBasedir(),
                "src/test/resources/testProject/testPom.xml" );

        step1SkipperPackage = initializeMojo(testPom, "skipper-package");
        step2SkipperUpload = initializeMojo(testPom, "skipper-upload");
        step3SkipperInstall= initializeMojo(testPom, "skipper-install");
        step4SkipperDelete = initializeMojoDelete(testPom, "skipper-delete");
    }

    private AbstractMojo initializeMojo(File testPom, String skipperPackage) throws Exception {

        MavenProject mavenProject = readMavenModel(testPom);

        AbstractMojo initMojo = (AbstractMojo) lookupMojo( skipperPackage , testPom );
        initializeMojoFields(mavenProject, initMojo);
        return initMojo;
    }

    private AbstractMojo initializeMojoDelete(File testPom, String skipperPackage) throws Exception {

        MavenProject mavenProject = readMavenModel(testPom);

        AbstractMojo initMojo = new SkipperDeleteMojo();
        initializeMojoFields(mavenProject, initMojo);
        return initMojo;
    }

    private void initializeMojoFields(MavenProject mavenProject, AbstractMojo mojo) throws NoSuchFieldException, IllegalAccessException {
        File workDirectory = new File( getBasedir(),
                "src/test/resources/testProject/target/skipper/");

        File overrideDirectory = new File( getBasedir(),
                "src/test/resources/testProject/target/classes/META-INF/skipper");

        //Set the properties
        setPrivateField(mojo, "project", mavenProject, false);
        setPrivateField(mojo, "workDirectory", workDirectory, true);
        setPrivateField(mojo, "overrideDirectory", overrideDirectory, true);
        setPrivateField(mojo, "SUBSTRING_SKIPPER_SEPARATOR",  "/skipper", true);

        setPrivateField(mojo, "skipperServerUri",  SKIPPER_SERVER_URI, true);
        setPrivateField(mojo, "repoName",  "local", true);
    }

    private void setPrivateField(Object objectInstance,String fieldName, Object fieldSetValue, boolean optional) throws NoSuchFieldException, IllegalAccessException {
        try{
            Field declaredField = objectInstance.getClass().getDeclaredField(fieldName);
            declaredField.setAccessible(true);
            declaredField.set(objectInstance, fieldSetValue);
        }catch(java.lang.NoSuchFieldException e){
            if(!optional){
                throw e;
            }
        }
    }

    private MavenProject readMavenModel(File testPom) {
        Model model = null;
        FileReader reader = null;
        MavenXpp3Reader mavenreader = new MavenXpp3Reader();
        try {
            reader = new FileReader(testPom);
            model = mavenreader.read(reader);
            model.setPomFile(testPom);
        }catch(Exception ex){}

        return new MavenProject(model);
    }


    /**
     * @throws Exception
     */
    @Test
    public void testSimpleStep1to3PackageToDelete() throws Exception
    {
        step1SkipperPackage.execute();
        step2SkipperUpload.execute();
        step3SkipperInstall.execute();

        Thread.sleep(10000);
        //TODO: Log message here

        step4SkipperDelete.execute();
    }

    @Test
    public void testStep4Delete() throws Exception
    {
        try{
            step4SkipperDelete.execute();
        }catch (Exception e){
            if(!e.getMessage().contains("404")){    //Allow this to be run even if steps 1 to 3 are not
                throw e;
            }
        }
    }    
}

And I have added the following two dependencies to my maven pom.xml:

<dependency>
        <groupId>org.eclipse.sisu</groupId>
        <artifactId>org.eclipse.sisu.plexus</artifactId>
        <version>0.3.3</version>
    </dependency>

    <dependency>
        <groupId>org.apache.maven.plugin-testing</groupId>
        <artifactId>maven-plugin-testing-harness</artifactId>
        <version>3.3.0</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.eclipse.sisu</groupId>
        <artifactId>org.eclipse.sisu.plexus</artifactId>
        <version>0.3.3</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>

So things that I am feeling are wrong but I don't know how to fix easily right now are and are in need of review:

  • I thought the maven testing harness and AbstractMojoTestCase should help with the mavenProject but I ended up needing to use MavenXpp3Reader.
  • It was bit annoying using reflection to set private fields within the MOJOs... I expected that everything would function like when the MOJOs are executed from mvn using e.g. mvn deploy or mvn skipper:skipper-install.

The original code I have forked locally is @: https://github.com/donovanmuller/spring-cloud-skipper-maven-plugin/blob/master/src/main/java/io/switchbit/SkipperPackageMojo.java

\$\endgroup\$
  • \$\begingroup\$ Have you tried using lookupConfiguredMojo() ? It returns plugin with injected @Parameters and doesn't require manual parsing of pom: stackoverflow.com/a/36064396/158037 \$\endgroup\$ – user158037 Apr 4 '18 at 15:27
  • \$\begingroup\$ Can you explain more in detail what: ` an extension to a maven mojo (spring-cloud-skipper-maven-plugin) ` exactly is? Are you trying to enhance the plugin? \$\endgroup\$ – khmarbaise Mar 11 at 15:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.