用Spring提供的JUnit框架扩展对DAO或Service层进行单元测试
2012-03-09 11:11
501 查看
用Spring提供的JUnit框架扩展对DAO或Service层进行单元测试
单元测试及其背后的组件易测性是贯穿Spring应用的核心理念之一。一直以来,与测试独立的Java对象相比,由于J2EEWeb组件必须运行于某种容器,或者还要与基于HTTP的Web环境交互,所以测试它们是一项艰巨而复杂的任务。
SpringMock包提供了一些扩展自JUnit框架的测试基类,这些基类简化了对依赖注射和事务管理的单元测试。
下面的内容来自csdn的一篇文章,算是helloworld教程吧。
一、Spring提供的JUnit框架扩展:
AbstractSpringContextTests:spring中使用spring上下文测试的Junit扩展类,我们一般不会使用这个类来进行单元测试,它是spring内部设计使用到的类
AbstractDependencyInjectionSpringContextTests:这是AbstractSpringContextTests的直接子类,支持依赖spring上下文的测试类,这个类不支持事务。
AbstractTransactionalSpringContextTests:这是AbstractDependencyInjectionSpringContextTests的直接子类,这个类一般应用在事务相关的测试中,一旦完成每个测试它就会正常地回滚事务,不会真正更新数据库,若要手动设置事务相关操作,你可以重载onSetUpInTransaction和onTearDownInTransaction方法,以便手工开始并提交事务,或者调用setComplete()方法。这个类也可以在没有事务的情况下,使用这个类。
AbstractTransactionalDataSourceSpringContextTests:这是AbstractTransactionalSpringContextTests的直接子类,它使用了Spring的基于JDBC的jdbcTemplate工具类,支持数据库级别的事务。
二、如何在你的TestCaseClass里取得springcontext
你的TestCaseClass必须继承的是上述四个AbstractXXXSpringContextTests中的其中一个,那么就必须实现下面这个方法来取得springcontext:
protectedabstractString[]getConfigLocations();
例如:
publicString[]getConfigLocations(){
String[]configLocations={"applicationContext.xml","hibernate-context.xml"};
returnconfigLocations;
}
请注意要加载的contextxmlfile的路径问题:上述的代码是基于classpath,因此applicationContext.xml和hibernate-context.xml必须放在classpath里(方法一是把xmlfiles放到WEB-INF/classes目录下,另一种方法就是在projectproperties里把xmlfiles的路径加到classpath里)
那么如果你一定要把contextxmlfiles放到WEB-INF目录下,也是可以的,那么应该基于file(基于file的相对路径是相对于projectrootfolder),代码如下:
<!--CRLF-->
<!--CRLF-->
<!--CRLF-->
<!--CRLF-->
AbstractXXXSpringContextTests就会根据根据getConfigLocations方法返回的contextxml位置的数组来加载并且对加载的Context提供缓存。这是非常重要的,因为如果你在从事一个大项目时,启动时间可能成为一个问题--这不是Spring自身的开销,而是被Spring容器实例化的对象在实例化自身时所需要的时间。例如,一个包括50-100个Hibernate映射文件的项目可能需要10-20秒的时间来加载上述的映射文件,如果在运行每个测试fixture里的每个测试案例前都有这样的开销,将导致整个测试工作的延时,最终有可能(实际上很可能)降低效率。
在某种极偶然的情况下,某个测试可能“弄脏”了配置场所,并要求重新加载--例如改变一个bean的定义或者一个应用对象的状态--你可以调用AbstractDependencyInjectionSpringContextTests上的setDirty()方法来重新加载配置并在执行下一个测试案例前重建applicationcontext
当类AbstractDependencyInjectionSpringContextTests(及其子类)装载你的ApplicationContext时,你可以通过Setter方法来注入你想要的来自context的bean,而不需要显式的调用applicationContext.getBean(XXX)。因为AbstractDependencyInjectionSpringContextTests会从getConfigLocations()方法指定的配置文件中帮你自动注入
下面的例子就是通过setter方法来获得context里的ProductManagerbean:
<!--CRLF-->
<!--CRLF-->
<!--CRLF-->
<!--CRLF-->
<!--CRLF-->
<!--CRLF-->
<!--CRLF-->
<!--CRLF-->
<!--CRLF-->
<!--CRLF-->
<!--CRLF-->
<!--CRLF-->
<!--CRLF-->
<!--CRLF-->
<!--CRLF-->
<!--CRLF-->
<!--CRLF-->
<!--CRLF-->
但是如果context里有多个bean都定义为一个类型(例如有多个bean都是ProductManagerclass类型的),那么对这些bean就无法通过setter方法来自动依赖注入(因为有多个bean同一个类型,不知要自动注入哪个)。在这种情况下你需要显示的调用applicationContext.getBean(XXX)来注入。如:
<!--CRLF-->
<!--CRLF-->
<!--CRLF-->
<!--CRLF-->
<!--CRLF-->
<!--CRLF-->
<!--CRLF-->
<!--CRLF-->
<!--CRLF-->
<!--CRLF-->
<!--CRLF-->
<!--CRLF-->
<!--CRLF-->
<!--CRLF-->
<!--CRLF-->
<!--CRLF-->
<!--CRLF-->
如果你的TestCase不使用依赖注入,只要不定义任何setters方法即可。或者你可以继承AbstractSpringContextTests--这个org.springframework.test包中的根类,而不是继承AbstractDependencyInjectionSpringContextTests(及其子类)。这是因为AbstractSpringContextTests只包括用来加载SpringContext的便利方法但没有自动依赖注入的功能。
单元测试及其背后的组件易测性是贯穿Spring应用的核心理念之一。一直以来,与测试独立的Java对象相比,由于J2EEWeb组件必须运行于某种容器,或者还要与基于HTTP的Web环境交互,所以测试它们是一项艰巨而复杂的任务。
SpringMock包提供了一些扩展自JUnit框架的测试基类,这些基类简化了对依赖注射和事务管理的单元测试。
下面的内容来自csdn的一篇文章,算是helloworld教程吧。
一、Spring提供的JUnit框架扩展:
AbstractSpringContextTests:spring中使用spring上下文测试的Junit扩展类,我们一般不会使用这个类来进行单元测试,它是spring内部设计使用到的类
AbstractDependencyInjectionSpringContextTests:这是AbstractSpringContextTests的直接子类,支持依赖spring上下文的测试类,这个类不支持事务。
AbstractTransactionalSpringContextTests:这是AbstractDependencyInjectionSpringContextTests的直接子类,这个类一般应用在事务相关的测试中,一旦完成每个测试它就会正常地回滚事务,不会真正更新数据库,若要手动设置事务相关操作,你可以重载onSetUpInTransaction和onTearDownInTransaction方法,以便手工开始并提交事务,或者调用setComplete()方法。这个类也可以在没有事务的情况下,使用这个类。
AbstractTransactionalDataSourceSpringContextTests:这是AbstractTransactionalSpringContextTests的直接子类,它使用了Spring的基于JDBC的jdbcTemplate工具类,支持数据库级别的事务。
二、如何在你的TestCaseClass里取得springcontext
你的TestCaseClass必须继承的是上述四个AbstractXXXSpringContextTests中的其中一个,那么就必须实现下面这个方法来取得springcontext:
protectedabstractString[]getConfigLocations();
例如:
publicString[]getConfigLocations(){
String[]configLocations={"applicationContext.xml","hibernate-context.xml"};
returnconfigLocations;
}
请注意要加载的contextxmlfile的路径问题:上述的代码是基于classpath,因此applicationContext.xml和hibernate-context.xml必须放在classpath里(方法一是把xmlfiles放到WEB-INF/classes目录下,另一种方法就是在projectproperties里把xmlfiles的路径加到classpath里)
那么如果你一定要把contextxmlfiles放到WEB-INF目录下,也是可以的,那么应该基于file(基于file的相对路径是相对于projectrootfolder),代码如下:
public String[]getConfigLocations(){
<!--CRLF-->
String[]configLocations={"file:WebContent/WEB-INF/applicationContext.xml" };
<!--CRLF-->
return configLocations;
<!--CRLF-->
}
<!--CRLF-->
AbstractXXXSpringContextTests就会根据根据getConfigLocations方法返回的contextxml位置的数组来加载并且对加载的Context提供缓存。这是非常重要的,因为如果你在从事一个大项目时,启动时间可能成为一个问题--这不是Spring自身的开销,而是被Spring容器实例化的对象在实例化自身时所需要的时间。例如,一个包括50-100个Hibernate映射文件的项目可能需要10-20秒的时间来加载上述的映射文件,如果在运行每个测试fixture里的每个测试案例前都有这样的开销,将导致整个测试工作的延时,最终有可能(实际上很可能)降低效率。
在某种极偶然的情况下,某个测试可能“弄脏”了配置场所,并要求重新加载--例如改变一个bean的定义或者一个应用对象的状态--你可以调用AbstractDependencyInjectionSpringContextTests上的setDirty()方法来重新加载配置并在执行下一个测试案例前重建applicationcontext
当类AbstractDependencyInjectionSpringContextTests(及其子类)装载你的ApplicationContext时,你可以通过Setter方法来注入你想要的来自context的bean,而不需要显式的调用applicationContext.getBean(XXX)。因为AbstractDependencyInjectionSpringContextTests会从getConfigLocations()方法指定的配置文件中帮你自动注入
下面的例子就是通过setter方法来获得context里的ProductManagerbean:
public class MyTestextends AbstractDependencyInjectionSpringContextTests{
<!--CRLF-->
ProductManagerproductManager;
<!--CRLF-->
<!--CRLF-->
public String[]getConfigLocations(){
<!--CRLF-->
String[]configLocations={"file:WebContent/WEB-INF/applicationContext.xml" };
<!--CRLF-->
return configLocations;
<!--CRLF-->
}
<!--CRLF-->
<!--CRLF-->
public
void
testGetProduct(){
<!--CRLF-->
assertEquals("tomson"
,productManager.getProductByName("tomson"
).getName());
<!--CRLF-->
}
<!--CRLF-->
<!--CRLF-->
//通过setter方法自动从context里注入productManagerbean,而不用显示调用applicationContext.getBean(XXX)
<!--CRLF-->
public
void
setProductManager(ProductManagerproductManager){
<!--CRLF-->
this
.productManager=productManager;
<!--CRLF-->
}
<!--CRLF-->
}
<!--CRLF-->
<!--CRLF-->
但是如果context里有多个bean都定义为一个类型(例如有多个bean都是ProductManagerclass类型的),那么对这些bean就无法通过setter方法来自动依赖注入(因为有多个bean同一个类型,不知要自动注入哪个)。在这种情况下你需要显示的调用applicationContext.getBean(XXX)来注入。如:
public class MyTestextends AbstractDependencyInjectionSpringContextTests{
<!--CRLF-->
ProductManagerproductManager;
<!--CRLF-->
<!--CRLF-->
public String[]getConfigLocations(){
<!--CRLF-->
String[]configLocations={"file:WebContent/WEB-INF/applicationContext.xml" };
<!--CRLF-->
return configLocations;
<!--CRLF-->
}
<!--CRLF-->
<!--CRLF-->
public
void
onSetUp(){
<!--CRLF-->
productManager=(ProductManager)applicationContext.getBean("productManager"
);
<!--CRLF-->
}
<!--CRLF-->
<!--CRLF-->
public
void
testGetProduct(){
<!--CRLF-->
assertEquals("tomson"
,productManager.getProductByName("tomson"
).getName());
<!--CRLF-->
}
<!--CRLF-->
}
<!--CRLF-->
<!--CRLF-->
如果你的TestCase不使用依赖注入,只要不定义任何setters方法即可。或者你可以继承AbstractSpringContextTests--这个org.springframework.test包中的根类,而不是继承AbstractDependencyInjectionSpringContextTests(及其子类)。这是因为AbstractSpringContextTests只包括用来加载SpringContext的便利方法但没有自动依赖注入的功能。
相关文章推荐
- 用Spring提供的JUnit框架扩展对DAO或Service层进行单元测试
- 用Spring提供的JUnit框架扩展对DAO或Service层进行单元测试
- Spring整合JUnit框架进行单元测试代码使用详解
- Spring整合Junit框架进行单元测试Demo
- 使用JUnit在struts+spring+hibernate框架环境下进行单元测试
- Spring整合JUnit框架进行单元测试代码使用详解
- Spring提供的JUnit框架扩展
- Spring提供的JUnit框架扩展
- 使用JUnit在struts+spring+hibernate框架环境下进行单元测试
- 使用JUnit在struts+spring+hibernate框架环境下进行单元测试
- Spring提供的JUnit框架扩展
- Spring整合Junit框架进行单元测试Demo
- Spring整合JUnit框架进行单元测试代码使用详解
- 在Myeclipse里使用Junit贴图教程与使用JUnit在struts+spring+hibernate框架环境下进行单元测试
- 使用JUnit在struts+spring+hibernate框架环境下进行单元测试
- Spring整合JUnit框架进行单元测试代码使用详解
- Spring整合JUnit框架进行单元测试代码使用详解
- maven下使用 junit对 spring进行单元测试
- 使用spring配合Junit进行单元测试的总结
- Spring配合Junit进行单元测试