Reputation: 16545
I have a multi-module Maven project. For the sake of this example, consider two modules:
data
consumer
Module consumer
has module data
as a dependency.
Module data
declares a bunch of core classes. There are tests under src/test
that use them. These tests require some long-winded object creation, so I have a class with some utility methods in it to create these objects. This utility class (SampleDataHelper
) is in the src/test
hierarchy.
I also have some tests in the consumer
module that need to create some of these long-winded objects. I want to use my SampleDataHelper
class (defined in data src/test
) in tests that reside in my consumer src/test
tree. Unfortunately, even though data
is a dependency of consumer
, consumer
can't see the classes that exist under data src/test
.
To combat this, I thought I might create another module (data-test
), and move SampleDataHelper
to it under src/main
. Then I would include data-test
as a test scope dependency of data
. Unfortunately, this introduces a circular dependency: data
uses data-test
, but data-test
also requires data
.
The only solution I've come up with is to place SampleDataHelper
under data src/main
under a test
package and hope that no real application code ever calls it.
How can I share my SampleDataHelper
class between modules without putting it under src/main
?
Upvotes: 197
Views: 80450
Reputation: 33749
So the problem is that (some) tests in the data
module depend on the SampleDataHelper
class? You can move the SampleDataHelper
class to src/main
of the data-test
module, if you at the same time move the tests (that depend on the specific class) to the src/test
of the data-test
module. Consequently, there would be no more circular dependencies.
Upvotes: 1
Reputation: 69329
Your Consumer project depends upon your Data project, therefore we are happy that Data must be built prior to Consumer. As a result, using the techniques suggested in the comments, I would ensure your Data project contains all the test code that you wish to share and configure the POM to produce a test JAR:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
Your Consumer project would then depend upon both the normal Data JAR artifact, plus the additional test-jar
artifact, with test scope of course:
<dependency>
<groupId>com.foo</groupId>
<artifactId>data</artifactId>
<version>1.0</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
I've used this approach on many occasions and it works well.
Upvotes: 249