stivlo
stivlo

Reputation: 85546

Integration tests with Maven in a Spring project

The question is how can I use different properties files for integration testing. Detailed explanation follows.

I'm trying to do in container integration tests with Maven, using tomcat7-maven-plugin. The project uses Spring and JPA. At present what I've figured out is the following:

All of this works and when I run mvn verify Tomcat is started.

However instead of using a regular database, I would like to use an in memory database. My database configuration is defined in the file src/main/resources/META-INF/spring/database.properties loaded through context:property-placeholder.

I tried to define an alternative file in src/test/resources/META-INF/spring/database.properties, but is ignored. I know that is possible to define system properties within tomcat7-maven-plugin, but I don't know how to use them to trigger loading of different properties files.

My tomcat7-maven-plugin configuration is the following:

<plugin>
    <groupId>org.apache.tomcat.maven</groupId>
    <artifactId>tomcat7-maven-plugin</artifactId>
    <version>2.1</version>
    <configuration>
        <port>9090</port>
        <path>/processing</path>
        <useTestClasspath>true</useTestClasspath>
        <systemProperties>
            <example.value.1>alpha</example.value.1>
        </systemProperties>
    </configuration>
    <executions>
        <execution>
            <id>start-tomcat</id>
            <phase>pre-integration-test</phase>
            <goals>
                <goal>run-war-only</goal>
            </goals>
            <configuration>
                <fork>true</fork>
            </configuration>
        </execution>
        <execution>
            <id>stop-tomcat</id>
            <phase>post-integration-test</phase>
            <goals>
                <goal>shutdown</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Properties are loaded by context-main.xml with the following line:

<context:property-placeholder location="classpath*:META-INF/spring/*.properties"/>  

I load context configuration from web.xml with the following:

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath*:META-INF/spring/context-*.xml</param-value>
</context-param>

Any suggestion on how to load alternative properties file for testing?

Upvotes: 2

Views: 1910

Answers (1)

stivlo
stivlo

Reputation: 85546

One way to do it, is with Maven profiles and the ant plugin. I suspect that is not the most elegant way, and I'm open to listen for better solution, but for now it solves my problem.

A profile is a way to have a different Maven configuration depending on command line arguments, so in my case to run the integration tests, I run the command mvn -Pintegration clean verify. Here integration is the name of the profile, and is defined in pom.xml, after the properties as follows:

<profiles>
    <profile>
        <id>standard</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
    </profile>
    <profile>
        <id>integration</id>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-antrun-plugin</artifactId>
                    <version>1.1</version>
                    <executions>
                        <execution>
                            <phase>test</phase>
                            <goals>
                                <goal>run</goal>
                            </goals>
                            <configuration>
                                <tasks>
                                    <echo>Copying test database.properties to ${project.build.outputDirectory}/META-INF/spring/</echo>
                                    <copy file="src/test/resources/META-INF/spring/database.properties"
                                        todir="${project.build.outputDirectory}/META-INF/spring/" verbose="true" overwrite="true" />
                                </tasks>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>

Using mvn clean package will instead use the standard profile. It's interesting to mention that profiles can also be defined outside the pom, in .m2/settings.xml

See also: Building For Different Environments with Maven 2 -- Notice that the overwrite parameter in the copy is essential or it will work only at random, and is not mentioned in the linked document.

Upvotes: 2

Related Questions