目前项目在使用Spring Test进行单元测试(其实算是集成测试了),有两个小知识想和大家分享下。
1.对于同时存在注解、xml配置的bean会以xml中的配置为准
例如spring配置文件如下:
<!-- application.xml -->
<context:component-scan base-package="com.itechlib.com.service" />
<!-- 在测试目录下定义stub类 -->
<bean id="userDao" class="com.itechlib.com.test.stub.UserDaoStubServiceImpl" />
Java代码如下:
@component("userService")
class UserServiceImpl implements IUserService {
@Resource(name="userDao")
private IUserDao userDao;
public void doUpdate(){
//...
userDao.update();
//...
}
}
这样在测试时UserServiceImpl
调用的就是stub
包下定义的userDao
的模拟类了。
2.同时运行多个测试类的时候,可以有不同的ContextConfiguration
配置
例如使用Junit TestSuite
来一次执行多个测试类,这时如果不同测试类的ContextConfiguration
配置不一样会怎么样呢?其实这些测试类都能够正确运行,因为spring会针对不同的configuration创建不同的ApplicationContext
,而且这些ApplicationContext
都会进行缓存,只会加载一次。
下面这些key不同就会生成不同的ApplicationContext
,具体见spring reference 文档 Context caching。
locations
(from @ContextConfiguration)
classes
(from @ContextConfiguration)
contextInitializerClasses
(from @ContextConfiguration)
contextLoader
(from @ContextConfiguration)
activeProfiles
(from @ActiveProfiles)
resourceBasePath
(from @WebAppConfiguration)
如果测试中破坏了ApplicationContext,可以对这个测试类声明@DirtiesContext
。
例如下面的写法会生成两个独立的ApplicationContext。
@ContextConfiguration(loader = SpringBeanTestContextLoader.class, locations = {
"classpath:test-resources/application/application.xml"})
class UserServiceTests extends AbstractJunit4SpringContextTests{
@Test
public void testUpdate(){
//...
}
}
@ContextConfiguration(loader = SpringBeanTestContextLoader.class, locations = {
"classpath:test-resources/application/application-custom.xml"})
class OrderServiceTests extends AbstractJunit4SpringContextTests{
@Test
public void testAdd(){
//...
}
}
了解这些你可以更好的规划你的测试配置,更好地测试各种场景和分支。