Testing Using Repositories
Note: This example improves the cookbook for testing repositories.
When developing a Maven plugin you often need to play with repositories. Suppose that the Mojo needs to download artifacts into your local repository.
You need annotate unit test with @MojoTest(realRepositorySession = true) to enable real repository session.
Then provided mock for MavenSession will have a real repository session with local repository configured.
Mock for MavenProject will also have mocked methods getRemote*Repositories.
Project dependencies for test
For real repository session you need to add resolver transport dependency in test scope to your pom.xml:
<dependency>
<groupId>org.apache.maven.resolver</groupId>
<artifactId>maven-resolver-connector-basic</artifactId>
<version>${resloverVersion}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.maven.resolver</groupId>
<artifactId>maven-resolver-transport-file</artifactId>
<version>${resloverVersion}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.maven.resolver</groupId>
<artifactId>maven-resolver-transport-http</artifactId>
<version>${resloverVersion}</version>
<scope>test</scope>
</dependency>
Example Mojo to test
import javax.inject.Inject;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.resolution.ArtifactRequest;
import org.eclipse.aether.resolution.ArtifactResolutionException;
import org.eclipse.aether.resolution.ArtifactResult;
/**
* Simple mojo for resolving artifacts.
*/
@Mojo(name = "simple-resolve")
public class SimpleResolveMojo extends AbstractMojo {
private final MavenProject project;
private final MavenSession session;
private final RepositorySystem repositorySystem;
@Parameter
private String artifact;
@Inject
SimpleResolveMojo(MavenProject project, MavenSession session, RepositorySystem repositorySystem) {
this.project = project;
this.session = session;
this.repositorySystem = repositorySystem;
}
@Override
public void execute() throws MojoExecutionException {
ArtifactRequest request =
new ArtifactRequest(new DefaultArtifact(artifact), project.getRemoteProjectRepositories(), null);
try {
ArtifactResult result = repositorySystem.resolveArtifact(session.getRepositorySession(), request);
getLog().info("Resolved artifact to " + result.getArtifact().getFile());
} catch (ArtifactResolutionException e) {
throw new MojoExecutionException("Failed to resolve artifact", e);
}
}
}
Unit test
import javax.inject.Inject;
import java.io.File;
import org.apache.maven.api.plugin.testing.InjectMojo;
import org.apache.maven.api.plugin.testing.MojoParameter;
import org.apache.maven.api.plugin.testing.MojoTest;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.logging.Log;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.mockito.Mockito;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Test class for simple artifact resolution mojo with repository system injection.
*/
@MojoTest(realRepositorySession = true)
class SimpleResolveMojoTest {
@TempDir
private File tempDir;
// inject the Maven session to customize it for tests
@Inject
private MavenSession session;
@Inject
private Log log;
@BeforeEach
void beforeEach() {
// optionally customize the session to use a temporary local repository
// default would be basedir/target/local-repo
session.getRequest().setLocalRepositoryPath(tempDir);
// other customizations can be done here, if needed
// session.getRequest().setRemoteRepositories(customRemoteRepositories());
// session.getRequest().setOffline(true);
// session.getUserProperties().setProperty("maven.repo.local.tail", "your local repository");
}
@Test
@InjectMojo(goal = "simple-resolve")
@MojoParameter(name = "artifact", value = "org.apache.commons:commons-lang3:3.20.0")
void artifactShouldBeResolved(SimpleResolveMojo mojo) {
assertDoesNotThrow(mojo::execute);
Mockito.verify(log, Mockito.times(1)).info(Mockito.contains("Resolved artifact to"));
}
@Nested
class NestedTest {
@Test
@InjectMojo(goal = "simple-resolve")
@MojoParameter(name = "artifact", value = "org.apache.commons:commons-lang3:3.20.0")
void artifactShouldBeResolved(SimpleResolveMojo mojo) {
assertDoesNotThrow(mojo::execute);
Mockito.verify(log, Mockito.times(1)).info(Mockito.contains("Resolved artifact to"));
}
}
}
Execute test
Calling mvn test will create <temp-directory>/org/apache/commons/commons-lang3/3.20.0/commons-lang3-3.20.0.jar file.



