Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot process locations AND classes for context configuration

Tags:

I have wrote following test:

@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath:META-INF/dataContext.xml"},classes = Configiuration.class) @ActiveProfiles("test") public class CityDaoImplTest { .... } 

I need to use configuration from xml file and from java class bur when I invoke

mvn test I seee following in console:

Tests in error:    initializationError(***.CityDaoImplTest): Cannot process locations AND classes for context configuration [ContextConfigurationAttributes@5bb21b69 declaringClass = '***.CityDaoImplTest', classes = '{***.Configiuration}', locations = '{classpath:META-INF/dataContext.xml}', inheritLocations = true, initializers = '{}', inheritInitializers = true, name = [null], contextLoaderClass = 'org.springframework.test.context.ContextLoader']; configure one or the other, but not both. 

How to fix it without rewriting configuration?

like image 585
gstackoverflow Avatar asked Jan 16 '15 08:01

gstackoverflow


People also ask

What is context configuration in spring?

@ContextConfiguration defines class-level metadata that is used to determine how to load and configure an ApplicationContext for integration tests.

What is the purpose of the @ContextConfiguration annotation in a Junit test?

At its core, the TestContext framework allows you to annotate test classes with @ContextConfiguration to specify which configuration files to use to load the ApplicationContext for your test.


2 Answers

From the Spring Docs:

Prior to Spring 3.1, only path-based resource locations were supported. As of Spring 3.1, context loaders may choose to support either path-based or class-based resources. As of Spring 4.0.4, context loaders may choose to support path-based and class-based resources simultaneously.

However, with spring-test there is a small caveat. It uses the SmartContextLoader which is based on AbstractDelegatingSmartContextLoader and unfortunately it is not so smart ;)

@Override public void processContextConfiguration(         final ContextConfigurationAttributes configAttributes) {      Assert.notNull(configAttributes, "configAttributes must not be null");     Assert.isTrue(!(configAttributes.hasLocations() && configAttributes.hasClasses()), String.format(         "Cannot process locations AND classes for context "                 + "configuration %s; configure one or the other, but not both.", configAttributes)); 

As shown in the code, locations and classes can not both be set.

So, how to fix this? Well, one solution is to add an extra config class such as the following:

@Configuration @ImportResource("classpath:META-INF/dataContext.xml") class TestConfig {  } 

And, in your test code use the following:

@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = {Configuration.class, TestConfig.class}) @ActiveProfiles("test") public class CityDaoImplTest { ... } 

Technically, this is rewriting the configuration but you do not have to alter your existing config, just add a new @Configuration class (and that class can even be in the same file as your test case).

like image 82
wassgren Avatar answered Oct 07 '22 00:10

wassgren


Even if is to late for you I will post my answer just to help the other ones which will read this.

Another solution is to declare your Configuration class as bean in dataContext.xml.

All you need to do is:

<bean class="com.packageWhereConfigClassIsPresent.Configuration"/> 

Hope it will help someone ;)

like image 32
Aditzu Avatar answered Oct 06 '22 23:10

Aditzu