We have typically known maven as a build automation and dependency management tool. But can it also help us share resources across artefacts? Well, yes this is possible. But what is the use case for such sharing. Let's say I am maintaining a project with multiple micro services. Out of one service is input to another. Although this design scales well and is easy to extend it is hard to test end to end, especially when I want to ensure a small change in one service does not break my overall system. One approach is to write integration tests on sample data but data may evolve over time and sample data will need to be updated frequently.
A more evolved approach would be to create a seperate repository just to test the entire flow. Lets call it Test Drive App. Test Drive App repo can have production data updated frequently in its class path. This will give us 2 options.
1. Test released artefacts with sample data within Test Drive App on local machine
2. Import resources from Test Drive App in to each individual service to test run it locally
Case 1 is simple. For case 2 we need to make the sample data available to the component service. We can copy all data in each component but that will increase redundancy and the repo size. This can be non trivial if the data being processed is in magnitudes of hundreds of GB. So we do not want to copy test data in each component.
Maven Dependency Plugin
<build><plugins><plugin><groupid>org.apache.maven.plugins</groupid><artifactid>maven-dependency-plugin</artifactid><version>3.6.0</version><executions><execution><id>unpack-test-resources</id><phase>generate-test-resources</phase><!--During test resource generation--><goals><goal>unpack</goal></goals><configuration><artifactitems><artifactitem><groupid>com.example.project.component</groupid><artifactid>test-drive-application</artifactid><version>0.0.0.1</version><type>jar</type><overwrite>true</overwrite><outputdirectory>${project.build.directory}/test-resources</outputdirectory><includes>ComponentFolder/**</includes> <!--Only unpack this folder--></artifactitem></artifactitems></configuration></execution></executions></plugin></plugins></build>
✨ What this does:
During the
generate-test-resourcesphase,Maven will unpack only
ComponentFolder/**folderInto
target/test-resources/
Without importing any .class files, no pollution.
Then, in your test code, you can load it from target/test-resources/:
Path resourceFolder = Paths.get("target", "test-resources", "ComponentFolder", "products");
Or mount it into Docker container in Test containers like:
container.withCopyFileToContainer( MountableFile.forHostPath(resourceFolder),
"/container/path/products"
);
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>${testcontainers.version}</version>
<scope>test</scope>
</dependency>
Comments
Post a Comment