One of my integration tests uses multiple Spring context files. It seems that Spring only autowires in beans from the first context and not the second. Does anyone know what I am doing wrong or how to work around the problem?
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:/META-INF/spring/applicationContext.xml", "classpath:/META-INF/spring/applicationContext-security.xml"}) @Configurable public class UserDetailsServiceImplIntegrationTest { @Autowired UserDataOnDemand dod; // @Autowired does not work for this bean from applicationContext-security.xml UserDetailsService userDetailsService; @Before public void setup() { dod.init(); // workaround for autowiring problem userDetailsService = (UserDetailsService)ctx.getBean("userDetailsService"); } @Test public void testLoadUser() { UserDetails ud = userDetailsService.loadUserByUsername("[email protected]"); Assert.assertEquals("[email protected]", ud.getUsername()); } }
I am using Spring 3.0.3.
Here is the stack trace when I uncomment the @Autowired line for UserDetailsService:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'za.co.acme.app.security.UserDetailsServiceImplIntegrationTest': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: org.springframework.security.core.userdetails.UserDetailsService za.co.acme.app.security.UserDetailsServiceImplIntegrationTest.userDetailsService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [org.springframework.security.core.userdetails.UserDetailsService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:286) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1064) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:374) at org.springframework.beans.factory.wiring.BeanConfigurerSupport.configureBean(BeanConfigurerSupport.java:140) at org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect.configureBean(AnnotationBeanConfigurerAspect.aj:59) at org.springframework.beans.factory.aspectj.AbstractDependencyInjectionAspect.ajc$afterReturning$org_springframework_beans_factory_aspectj_AbstractDependencyInjectionAspect$2$1ea6722c(AbstractDependencyInjectionAspect.aj:89) at za.co.acme.app.security.UserDetailsServiceImplIntegrationTest.(UserDetailsServiceImplIntegrationTest.java:25) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) at java.lang.reflect.Constructor.newInstance(Constructor.java:513) at org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:202)
The bean is definitely there since the "by name" lookup works, and it is of the correct type.
By default the ApplicationContext is loaded using the GenericXmlContextLoader which loads a context from XML Spring configuration files. You can then access beans from the ApplicationContext by annotating fields in your test class with @Autowired , @Resource , or @Inject .
Autowiring using property type. Allows a property to be autowired if exactly one bean of property type exists in the container. If more than one exists, it's a fatal exception is thrown, which indicates that you may not used byType autowiring for that bean.
A workaround is to create a new single configuration file (let's call it "test-configuration.xml") which is including the both applicationContext.xml and applicationContext-security.xml. Then you can use these configurations within your tests.
test-configuration.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<import resource="classpath:/META-INF/spring/applicationContext.xml"/>
<import resource="classpath:/META-INF/spring/applicationContext-security.xml"/>
</beans>
UserDetailsServiceImplIntegrationTest.java:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/test-configuration.xml")
@Configurable
public class UserDetailsServiceImplIntegrationTest {
...
}
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