问题
We have large application written in Spring 3. I need to write JUnit test checking behavior of some service. It is not a unit but part of a system. There are some services and repositories working together insite it -> lot of injected beans inside. The app also uses aspects.
My question is. How to manage config and beans in this case of tests? I need to use beans defined in app configes and in tests only redefine beans using persistence to work with a embedded db. So I need to use beans from src as they are defined and override only some causing troubles (persistance beans, beans using webservices,...) In test package I made Config class definying beans for persistance, using datasource for hsql. But I don`t know what next. I tried to annotate Test config class with:
@Configuration
@EnableAspectJAutoProxy
@EnableTransactionManagement(mode = AdviceMode.ASPECTJ, proxyTargetClass = true)
@ComponentScan(basePackages = "com.example.our.app")
public class MyTestConfig implements TransactionManagementConfigurer {
to scan whole application and use configuration of beans from src folder. But this also takes configs from other tests causing problems. Is this whole good strategy or not? What now - use excludeFilters to remove other test configs? Or is this strategy whole bad?
thanks
回答1:
I think best way here to use is Spring profiles. Check here now to use H2 for tests with profiles.
回答2:
You can selectively overwrite beans with the context merging functionality supplied by the @ContextHierarchy
annotation.
In order to get this working for your use case you will have to create a base context that scans your app for Spring beans:
@Configuration
@ComponentScan({"com.example.our.app"})
public class MyTestConfig implements TransactionManagementConfigurer {
Then create a base class that utilizes this context and names it - this won't work with named contexts!:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextHierarchy( {
@ContextConfiguration(name="testContext", classes = MyTestConfig.class),
})
public class BaseTest {
And finally write a unit test that extends the base class and defines a new context under the same name to overwrite individual beans with a test specific configuration:
@ContextHierarchy(@ContextConfiguration(name="testContext", classes = OneUnitTest.Config.class))
public class OneUnitTest extends AggroBaseTest {
@Configuration
static class Config {
..
}
回答3:
You can also override with another import
<beans>
<import resource="classpath*:applocationContext.xml" />
<bean id="dataSourceFactory" class=com.demo.MyNewClass/>
</beans>
And in you class if you
this.applicationContext.getBean("dataSourceFactory");
retrieve the class, you would see the instance of new class
Further
<bean id="dataSourceFactory" class="org.springframework.jdbc.datasource.DriverManagerDataSource" >
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
So there are different ways you can override the default behaviour
来源:https://stackoverflow.com/questions/15573822/junit-test-in-spring-overriding-and-ignoring-beans-from-application-other-conf