How to use mockito with maven testing harness

2.4k views Asked by At

The maven plugin I am developing now injects some dependencies using Google Guice with JSR-330. For unit testing I am using maven-plugin-testing-harness. The plugin works perfectly. But there is a problem with tests. I want to inject mocked components into mojo, but still there are real objects in tests.

I've tried to write my custom test module as it's said in Google Guice Bound Field, but it didn't work. After some debugging I found out that Plexus container doesn't allow to use custom modules.

There are my mojo:

package my.maven.plugins.myplugin;

import my.maven.plugins.myplugin.component.MyComponent;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;

import javax.inject.Inject;

@Mojo(name = "resolve-property-value")
public class MyMojo extends AbstractMojo {

    private final MyComponent component;

    @Parameter(readonly = true, defaultValue = "${project}" )
    private MavenProject project;

    @Inject
    public MyMojo(MyComponent component) {
        this.component = component;
    }

    @Override
    public void execute() {
        String value = component.resolvePropertyValue();
        project.getProperties().setProperty("some.property", value);
    }
}

Component's interface:

package my.maven.plugins.myplugin.component;

public interface MyComponent {

    String resolvePropertyValue();
}

And implementation

package my.maven.plugins.myplugin.component.impl;

import my.maven.plugins.myplugin.component.MyComponent;

import javax.inject.Named;

@Named
public class MyComponentImpl implements MyComponent {

    @Override
    public String resolvePropertyValue() {
        return "someValue";
    }
}

Test:

package my.maven.plugins.myplugin;

import my.maven.plugins.myplugin.component.MyComponent;
import org.apache.maven.plugin.Mojo;
import org.apache.maven.plugin.testing.MojoRule;
import org.apache.maven.project.MavenProject;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.util.Properties;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.doReturn;

public class MyMojoTest {

    @Mock
    private MyComponent component;

    @Rule
    public MojoRule mojoRule = new MojoRule();

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void should_set_some_property() throws Exception {
        doReturn("testValue").when(component).resolvePropertyValue();
        MavenProject project = new MavenProject();
        Mojo goal = mojoRule.lookupConfiguredMojo(project, "resolve-property-value");
        goal.execute();
        Properties properties = project.getProperties();
        assertTrue(properties.containsKey("some.property"));
        assertEquals("testValue", properties.get("some.property"));
    }
}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>my.maven.plugins</groupId>
    <artifactId>my-plugin</artifactId>
    <version>0.1.0-SNAPSHOT</version>
    <packaging>maven-plugin</packaging>

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

        <maven.version>3.6.0</maven.version>
        <maven-test.version>3.3.0</maven-test.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-core</artifactId>
            <version>${maven.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-plugin-api</artifactId>
            <version>${maven.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.maven.plugin-tools</groupId>
            <artifactId>maven-plugin-annotations</artifactId>
            <version>${maven.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>21.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.maven.resolver</groupId>
            <artifactId>maven-resolver-api</artifactId>
            <version>1.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-compat</artifactId>
            <version>${maven.version}</version>
            <scope>test</scope>
        </dependency>

        <!-- Test dependencies -->
        <dependency>
            <groupId>org.apache.maven.plugin-testing</groupId>
            <artifactId>maven-plugin-testing-harness</artifactId>
            <version>${maven-test.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <version>2.23.4</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-plugin-plugin</artifactId>
                    <version>${maven.version}</version>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>

Is there any way to use mockito in plugin unit tests?

1

There are 1 answers

1
Gibadullina Elvira On

I suppose there is no "magic" ways to inject mocked components. So I've decided to put it into container explicitly in setUp section

@Before
public void setUp() {
    MockitoAnnotations.initMocks(this);
    mojoRule.getContainer().addComponent(component, MyComponent.class, "");
}