Charles
Charles

Reputation: 685

How to set up spring context:component-scan to scan "src/main/java" instead of "src/test.java" in unit test env

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

Answers (3)

Ayub Malik
Ayub Malik

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

MarcelK
MarcelK

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

Wins
Wins

Reputation: 3460

To get BeanFactory you can implement BeanFactoryAware

Upvotes: 1

Related Questions