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
?
data
) before I can even compile my second module (consumer
).
mvn package
, but it should work just fine in a single step build when you use mvn install
or mvn deploy
. Just a quick note. In one of our large projects we have a wrapper over junit's TestBase
and it's located in src/main
which I don't consider to be a good idea either.
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.
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.
SampleDataHelper
be moved from either the data
module or the consumer
module (as appropriate) into data-test
. Unfortunately I don't find this a very "neat" solution as it moves my tests out of the module they test, and into a different one. (Strictly speaking, you only said to move the data
tests, but I think I'd find myself moving both for consistency). But thank you for your answer. :-)
data-test
module should depend on the data
module (and not the other way around). To avoid the circular dependency, all tests that currently reside in the data
module that uses the SampleDataHelper
must be moved to the data-test
module.
Success story sharing