Search code examples
javaspringmaven-2junitclasspath

Test-resources of dependencies not in classpath?


I have a multi module Spring project that I set up using Maven:

my-root (pom)
    - my-logic
    - my-webapp (depending on my-logic)
    - my-consoleapp (depending on my-logic)

My Test classes inherit from AbstractTransactionalJUnit4SpringContextTests and use @ContextCofiguration for setting up the ApplicationContext.

E.g. the test class for a Spring Controller:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { 
  "classpath:applicationContext-logic-test.xml",
  "classpath:applicationContext-web-test.xml"})
public class ControllerTest extends AbstractTransactionalJUnit4SpringContextTests {

  @Autowired
    private ApplicationContext applicationContext;
    ...
}

As you can see there is a config XML per module. I have seperate configs for tesing, residing in test/resources of each module (and additionaly having the suffix "-test"). This all works (the class compiles, runs and the JUnit tests are successful) if I run the JUnit test in Eclipse.

Now to my problem: Running the test using Maven will NOT work! (e.g. with "Run As">"Maven install" on my-root (I use m2eclipse)). Specifically, it will throw the following exception:

java.io.FileNotFoundException: class path resource [applicationContext-logic-test.xml] cannot be opened because it does not exist`

It seems that Maven does not add the files from my-logic/src/test/resources to the classpath that is set up when running the unit tests of my-webapp.

How can I fix that?


Solution

  • It seems that Maven does not add the files from my-logic/src/test/resources to the classpath that is set up when running the unit tests of my-webapp.

    No, indeed, it doesn't. First, Maven uses binary dependencies that are always resolved through the local repository. And second, binary dependencies don't include test stuff.

    But what you could do is:

    1. configure the my-logic module to create a test JAR using jar:test-jar
    2. configure the my-webapp module to depend on this test JAR (using a test scope).

    For #1, you'll have to configure the Maven Jar Plugin in the pom.xml of my-logic:

    <project>
      <build>
        <plugins>
         <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>
        </plugins>
      </build>
    </project>
    

    And Maven will create a JAR with the content of target/test-classes during package and install / deploy it.

    For #2, declare a dependency on the test JAR in the pom.xml of my-webapp:

    <project>
      ...
      <dependencies>
        <dependency>
          <groupId>com.myco.app</groupId>
          <artifactId>foo</artifactId>
          <version>1.0-SNAPSHOT</version>
          <type>test-jar</type>
          <scope>test</scope>
        </dependency>
      </dependencies>
      ...
    </project>
    

    That should do it.