@Solubris
[ABOUT][BLOG][PROJECTS][WORKS]
// Posted on January 8, 2013 by T W

Overriding spring context for testing
 

Blog posts < Recent >
 



Blog posts < Coming soon >
 



When writing tests for a spring app, it is too easy to just copy the main context files into
"src/test/resources"
and then modify to suit the testing requirements.
However, this leads to some problems: Therefore, the best practice is to override the main context files, and only affect the beans that have a different config for testing.
So this blog post presents a nice way (I think) to do this.

Create directory for spring test overrides
 

The best solution is to create a unique dir for the spring test resources as follows:
"src/test/resources/META-INF/spring-test/"


Define test override context file
 

I recommend creating a single context override file as follows:
"src/test/resources/META-INF/spring-test/applicationContext-test-override.xml"


Define correct @ContextConfiguration
 

This is the context config to use in the test classes:
@ContextConfiguration(locations = { "classpath*:/META-INF/spring/applicationContext*.xml",
			"classpath*:/META-INF/spring-test/applicationContext-test-override.xml" })
This forces the test context files to be loaded after the main context files. If you want multiple test overrides, you could use the following:
@ContextConfiguration(locations = { "classpath*:/META-INF/spring/applicationContext*.xml",
			"classpath*:/META-INF/spring-test/applicationContext*.xml" })


Override data source
 

For testing, normally want to use a different data source. Create a file:
"src/test/resources/META-INF/spring-test/database.properties"
. Place test database connection details in here. Add the following to the application context test override:
<context:property-placeholder
	location="classpath:META-INF/spring-test/database.properties" ignore-unresolvable="true" order="-1"/>
Property files can't be overridden like context files as the property resolver returns on the first property to match.
This means the test properties need to come before the main properties. The
order="-1"
achieves this.
We don't want to repeat all the properties in the test files, only the ones that are different. Therefore,
ignore-unresolvable="true"
is required to allow the property resolver to continue looking in other property files.
For testing, normally want to recreate database every time tests are run. This can be achieved by including the following:
<util:properties id="jpaPropertyMap">
	<prop key="hibernate.hbm2ddl.auto">create</prop>
</util:properties>

<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
	<property name="persistenceUnitName" value="persistenceUnit" />
	<property name="dataSource" ref="dataSource" />
	<property name="jpaPropertyMap" ref="jpaPropertyMap" />
</bean>
NOTE: this is redefining the entityManagerFactory, so you need to make sure this matches the one you have in the main context. This is not ideal as there is some duplication, however, its hard to avoid in this case.

Disable scheduled tasks
 

During testing, normally don't want scheduled tasks to run. These can be disabled by using no-op instances of the spring task beans:
<bean id="myScheduler" class="solubris.test.NopTaskScheduler"/>
<bean id="myExecutor" class="solubris.test.NopTaskExecutor"/>
<bean id="lifecycleProcessor" class="solubris.test.NopLifecycleProcessor"/>
These classes can be download here
Of course the task beans still need to be tested, so another test should be written just for that.

Disable other beans
 

There are many ways to override beans in spring, here are some: Suggestions are welcome on other ways to override beans.

comments powered by Disqus