Reputation: 685
I am new to spring and Maven. And recently I build spring MVC project and use maven to manage the project structure and dependencies.
And when I write the unit test, I meet a problem which is I cannot get the beans from "src/main/java", and it seems that the context only load the beans from "src/test/java".
Here is my code.
Unit test: src/test/java/com/web/component/form
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath*:META-INF/spring/applicationContext-web-test.xml"})
public class FormTest {
@Autowired
private BeanFactory beanFactory; // I override this bean by myself
}
Config XML file: src/test/resources/META-INF/spring/applicationContext-web-test.xml Here the following component scan seems only scan the beans defined in src/test/java, not src/main/java.
<context:component-scan base-package="com.web">
<context:exclude-filter expression=".*_Roo_.*" type="regex"/>
<context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
</context:component-scan>
The override BeanFactory class is in src/main/java/com/web/helper/.
Error:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.web.helper.BeanFactory] 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.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:924)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:793)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:707)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:478)
... 41 more
So, I want to ask that is there a way to change the component scan, and make it scan the beans/classes defined in src/main/java instead of src/test/java in the spring maven unit test?
Upvotes: 4
Views: 8841
Reputation: 2578
As somebody else has mentioned you do not include the source folders inside the component scan.
Maven will automatically add classes in src/test/java and src/main/java to the classpath. In that order.
So the problem might be due to your BeanFactory implementation. Make sure you BeanFactory implementation has a default constructor and is created successfully. To force ordering you could put a @DependsOn annotation (but I don,t think this is the problem)
Upvotes: 1
Reputation: 283
Have you tried importing your normal application context in the test context.xml? Like this:
<import resource="classpath:applicationContext.xml" />
This will probably cause some problems though (Springockito can help to easily replace unwanted beans with mocks).
I don't remember encountering such problems. But Spring has some limitations regarding wildcards in classpath declarations of resources - maybe wildcards in component scan are limited in a similar way? I usually have some base context that is being importer in the test on, so the component scan is set up there.
Have you found the answer?
Upvotes: 1