views:

3271

answers:

6

I have a large application spread across multiple Spring bean definition xml files. In my test suite I manually load up the XML files I need using a FileSystemXmlApplicationContext to perform the tests I want to run. This reduces test set up time and allows me to use the same exact configuration files that are used in production.

Now I'm trying to use Spring's transactional test base classes which take the config locations and load the context for me. For some reason when the application context is created Spring cannot find any of the config files. This is confusing because I run the test from the same working directory as when I load the config myself using FileSystemXmlApplicationContext. If I prepend all my config locations with "file:" the paths I specify in my test are found, but any files that are imported or referenced by beans defined in the config (e.g. properties files) cannot be found. What's the deal? Can I get tests that extend the spring context test classes to work the same as the ones where I create the context myself?

For example, creating the context like this works fine:

ApplicationContext ctx = new FileSystemXmlApplicationContext(new String[] { "WEB-INF/services-context.xml"})

If I extend AbstractTransactionalDataSourceSpringContextTests the following does not find services-context.xml:

@Override
protected String[] getConfigLocations() {
   return new String[] { "WEB-INF/services-context.xml"};
}

This finds services-context, but the PropertyPlaceholderConfigurer defined in there fails to find it's properties files.

 @Override
 protected String[] getConfigLocations() {
    return new String[] { "file:WEB-INF/services-context.xml"};
 }
A: 

Your config locations are relative URIs, and will be interpreted as such by the base test class, with the URI being resolved relative to the location of the test class itself. Try using fully qualified URIs, or use relative URI taking into account where the test class is.

skaffman
Prepending with file: forces the use of qualified uri's, but then that causes the problem where files referenced in the config file cannot be found.
Adam B
A: 

In addition to overriding getConfigLocations I also overrode loadContext and used a trusty fileSystemXmlApplicationContext in there.

 @Override
 protected String[] getConfigLocations() {
     return new String[] { "WEB-INF/services-config.xml" };
 }

 @Override
 protected ConfigurableApplicationContext loadContext(String[] locations) throws Exception {
     return new FileSystemXmlApplicationContext(locations);
  }
Adam B
A: 

We put all of our Spring config and properties files in the classpath, which keeps things simple - we can just extend our test classes from a base class like:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={
     "/spring/*.xml", 
     "/testSpring/*.xml" })
public abstract class AbstractIntegrationTest  {

Here, the paths are all paths in classpath.

If you don't want to do that, have you checked how you are referencing the properties files in your services-context.xml? I suspect that if you add file: to your context configuration, then you'll also need to add this to your property file reference. You could perhaps just use a separate test Spring config file to change the definition of your property placeholder, and place this at the end of your list of context files - its definitions will then override those defined in earlier files.

paulcm
A: 

Can't you use classpath XML factories like ClassPathXmlApplicationContext?

atc
A: 

i have a similar issue when creating a test: i have a class that works as a base that is extended by an other that performs tests, but it doesn't find the applicationContext.xml.

@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations={"classpath:web/WEB-INF/applicationContext.xml"}) public class BaseSpringContextTest extends AbstractJUnit4SpringContextTests {}

The error i get when running the "TestClass extends BaseSpringContextTest" test is:

    7-gen-2010 16.23.25 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 
INFO: Loading XML bean definitions from class path resource [web/WEB-INF/applicationContext.xml]
[...]
org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(JUnitTestRunner.java:888)
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from class path resource [web/WEB-INF/applicationContext.xml]; nested exception is java.io.FileNotFoundException: class path resource [web/WEB-INF/applicationContext.xml] cannot be opened because it does not exist
        [...]
Caused by: java.io.FileNotFoundException: class path resource [web/WEB-INF/applicationContext.xml] cannot be opened because it does not exist

my applicationContext.xml is located at web/WEB-INF/applicationContext.xml and my test class is at test/it/com/service/impl/ComServiceImpl.java

mox601
A: 

Adam I have explained the solution in http://www.skill-guru.com/blog/2009/12/16/aspect-oriented-programmingaop-with-spring/#comments

vsingh