In order to provide Spring testing functionality to standard JUnit tests, we need to first make sure to run the test class with @RunWith
annotation set to SpringJUnit4ClassRunner
and provide configuration classes using @ContextConfiguration
or @ContextHierarchy
.
You can read other scenarios related to @ContextConfiguration and @ContextHierarchy here.
In this article, we will see how to use composed annotation annotated with either @ContextConfiguration
or @ContextHierarchy
to build the application context.
Composed @ContextConfiguration Annotation
We provide the configuration classes or the XML context file locations using @ContextConfiguration
. See here for an example. One can also declare the @ContextConfiguration
as a meta-annotation, that is, a custom annotation which is composed of @ContextConfiguration
.
ComposedContextConfiguration:
package com.javarticles.spring; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.springframework.test.context.ContextConfiguration; @ContextConfiguration @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface ComposedContextConfiguration { }
Spring Tests using composed annotation
We will now use the above defined meta-annotation to define spring based tests.
A:
package com.javarticles.spring; public class A { }
ClassWithComposedAnnotationContainingContextConfiguration:
package com.javarticles.spring; import static org.junit.Assert.assertNotNull; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @ComposedContextConfiguration public class ClassWithComposedAnnotationContainingContextConfiguration { @Autowired private A beanA; @Test public void verifyBeanAConfigured() { assertNotNull(beanA); } @Configuration static class Config { @Bean A beanA() { return new A(); } } }
Spring looks for @ContextConfiguration
and @ContextHierarchy
not in the root test class but also its super classes. Likewise it also traverses through the annotations declared at each class to see if it can find @ContextConfiguration
or @ContextHierarchy
and this includes even the meta-annotations.
Output:
Mar 02, 2016 2:47:56 AM org.springframework.test.context.support.AbstractContextLoader generateDefaultLocations INFO: Could not detect default resource locations for test class [com.javarticles.spring.ClassWithComposedAnnotationContainingContextConfiguration]: no resource found for suffixes {-context.xml}. Mar 02, 2016 2:47:56 AM org.springframework.test.context.support.AbstractDelegatingSmartContextLoader processContextConfiguration INFO: AnnotationConfigContextLoader detected default configuration classes for context configuration [[email protected] declaringClass = 'com.javarticles.spring.ClassWithComposedAnnotationContainingContextConfiguration', classes = '{class com.javarticles.spring.ClassWithComposedAnnotationContainingContextConfiguration$Config}', locations = '{}', inheritLocations = true, initializers = '{}', inheritInitializers = true, name = [null], contextLoaderClass = 'org.springframework.test.context.ContextLoader']. Mar 02, 2016 2:47:56 AM org.springframework.test.context.support.DefaultTestContextBootstrapper getDefaultTestExecutionListenerClassNames INFO: Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener] Mar 02, 2016 2:47:56 AM org.springframework.test.context.support.DefaultTestContextBootstrapper instantiateListeners INFO: Could not instantiate TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their required dependencies) available. Offending class: [javax/servlet/ServletContext] Mar 02, 2016 2:47:56 AM org.springframework.test.context.support.DefaultTestContextBootstrapper instantiateListeners INFO: Could not instantiate TestExecutionListener [org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their required dependencies) available. Offending class: [org/springframework/transaction/interceptor/TransactionAttribute] Mar 02, 2016 2:47:56 AM org.springframework.test.context.support.DefaultTestContextBootstrapper instantiateListeners INFO: Could not instantiate TestExecutionListener [org.springframework.test.context.transaction.TransactionalTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their required dependencies) available. Offending class: [org/springframework/transaction/interceptor/TransactionAttributeSource] Mar 02, 2016 2:47:56 AM org.springframework.test.context.support.DefaultTestContextBootstrapper getTestExecutionListeners INFO: Using TestExecutionListeners: [org.springframework.test[email protected]1ae369b7, org.springframewor[email protected]6fffcba5, org.springfra[email protected]34340fab] Mar 02, 2016 2:47:56 AM org.springframework.context.support.GenericApplicationContext prepareRefresh INFO: Refreshing [email protected]6e6d5e: startup date [Wed Mar 02 02:47:56 PST 2016]; root of context hierarchy
Download the source code
This was an example about using spring composed @ContextConfiguration.