I'm looking for best practices for setting up unit and integration tests using Spring.
I usually use 3 kind of tests:
Currently I only have tests of the second category, which is the tricky part. I set-up a base test class like:
@ContextConfiguration(locations = { "/my_spring_test.xml" })
public abstract class AbstractMyTestCase extends AbstractJUnit4SpringContextTests
And "unit" tests like:
public class FooTest extends AbstractMyTestCase
with autowired attributes.
What's the best way to run the test in a different (integration test) environment? Subclass the test and override the ContextConfiguration?
@ContextConfiguration(locations = { "/my_spring_integration_test.xml" })
public class FooIntegrationTest extends FooTest
Would this work (I cannot currently easily test it here)? The problem with this approach is that "@ContextConfiguration(locations = { "/my_spring_integration_test.xml" })" is duplicated a lot.
Any suggestions?
Regards, Florian
I extended the GenericXmlContextLoader
public class MyContextLoader extends GenericXmlContextLoader {
and overrote the
protected String[] generateDefaultLocations(Class<?> clazz)
method to collect the config file names of a directory which I can specify by a SystemProperty (-Dtest.config=).
I also modified the follwowing method to NOT modify any locations
@Override
protected String[] modifyLocations(Class<?> clazz, String... locations) {
return locations;
}
I use this context loader like this
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = MyContextLoader.class)
public class Test { .... }
Running the test with a SystemProperty indicating the source of the config files enables you now to use completely different configurations.
The usage of a SystemProperty is of course only one strategy to specify the configuration location. You can do whatever you want in generateDefaultLocations()
.
EDIT:
This solution enables you to use complete different application context configurations (e.g. for mock objects) and not only different properties. You do not need a build step to deploy everything to your "classpath" location. My concrete implementation also used the users name as default to look for a configuration directory (src/test/resources/{user}) if no system property is given (makes it easy to maintain specific test environments for all developers on the project).
The usage of the PropertyPlaceholder ist still possible and recommended.
EDIT:
Spring Version 3.1.0 will support XML profiles/Environment Abstraction which is similar to my solution and will enable the choice of configuration files for different environments/profiles.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With