45fan.com - 路饭网

搜索: 您的位置主页 > 电脑频道 > 电脑教程 > 阅读资讯:spring DAO集成测试的方法

spring DAO集成测试的方法

2016-08-30 20:59:38 来源:www.45fan.com 【

spring DAO集成测试的方法

在进行dao的集成测试时候,数据清理,察看数据都是比较麻烦的事情,使用Spring-mock.jar可以帮助我们简化着一个过程。我举一个简单的例子,说明一下如何使用spring-mock。

首先是po, hbm.xml, dao, daoimpl没什么好说的:

代码
 
  1. Customer.java:
  2.  
  3. packagerst.spring.mock;
  4.  
  5. importjava.io.Serializable;
  6.  
  7. /**@authorHibernateCodeGenerator*/
  8. publicclassCustomerimplementsSerializable{
  9.  
  10. /**identifierfield*/
  11. privateLongid;
  12.  
  13. /**nullablepersistentfield*/
  14. privateStringname;
  15.  
  16. /**fullconstructor*/
  17. publicCustomer(Stringname){
  18. this.name=name;
  19. }
  20.  
  21. /**defaultconstructor*/
  22. publicCustomer(){
  23. }
  24.  
  25. publicLonggetId(){
  26. returnthis.id;
  27. }
  28.  
  29. publicvoidsetId(Longid){
  30. this.id=id;
  31. }
  32.  
  33. publicStringgetName(){
  34. returnthis.name;
  35. }
  36.  
  37. publicvoidsetName(Stringname){
  38. this.name=name;
  39. }
  40.  
  41. }
  42.  
  43. Customer.hbm.xml:
  44.  
  45. <?xmlversion="1.0"encoding="UTF-8"?>
  46. <!DOCTYPEhibernate-mappingPUBLIC
  47. "-//Hibernate/HibernateMappingDTD//EN"
  48. "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
  49. <hibernate-mappingpackage="rst.spring.mock">
  50. <classname="Customer"table="customer">
  51. <idname="id"column="id"type="long"unsaved-value="null">
  52. <generatorclass="identity"/>
  53. </id>
  54. <propertyname="name"column="name"type="string"/>
  55. </class>
  56.  
  57. </hibernate-mapping>
  58.  
  59. CustomerDAO:
  60. /*
  61. *Createdon2005-3-25
  62. */
  63. packagerst.spring.mock;
  64.  
  65. importorg.springframework.dao.DataAccessException;
  66.  
  67. /**
  68. *@authorrst
  69. *
  70. */
  71. publicinterfaceCustomerDAO{
  72. publicvoidadd(Customercustomer)throwsDataAccessException;
  73. }
  74.  
  75. CustomerDAOImpl:
  76.  
  77. packagerst.spring.mock;
  78.  
  79. importorg.springframework.dao.DataAccessException;
  80. importorg.springframework.orm.hibernate.support.HibernateDaoSupport;
  81.  
  82. /**
  83. *Classdescription.
  84. *
  85. *@authorrst
  86. */
  87. publicclassCustomerDAOHibernateImplextendsHibernateDaoSupportimplementsCustomerDAO{
  88.  
  89. publicvoidadd(Customercustomer)throwsDataAccessException{
  90. this.getHibernateTemplate().save(customer);
  91. }
  92. }
  93.  

然后测试的基类SpringDAOTestCase继承自AbstractTransactionalDataSourceSpringContextTests,目前只有一个指定测试用xml文件位置的逻辑。

代码
 
  1. packagerst.spring.mock;
  2.  
  3. importorg.springframework.test.AbstractTransactionalDataSourceSpringContextTests;
  4.  
  5. /**
  6. *Classdescription.
  7. *
  8. *@authorrst
  9. */
  10. publicabstractclassSpringDAOTestCaseextendsAbstractTransactionalDataSourceSpringContextTests{
  11.  
  12. protectedString[]getConfigLocations(){
  13. returnnewString[]{"test.xml"};
  14. }
  15.  
  16. }

接着是我们真正测试的类CustomerDAOTest.java:

代码
 
  1. packagerst.spring.mock;
  2.  
  3. /**
  4. *Classdescription.
  5. *
  6. *@authorrst
  7. */
  8. publicclassCustomerDaoTestextendsSpringDAOTestCase{
  9.  
  10. privateCustomerDAOHibernateImplcustomerDAO;
  11.  
  12. protectedvoidonSetUpInTransaction()throwsException{
  13. super.onSetUpInTransaction();
  14. //this.setPopulateProtectedVariables(true);
  15. customerDAO=(CustomerDAOHibernateImpl)this.applicationContext.getBean("customerDAO");
  16. }
  17.  
  18. protectedvoidonTearDownInTransaction(){
  19. customerDAO=null;
  20. }
  21.  
  22. publicvoidtestInsert(){
  23. Customercustomer=newCustomer();
  24. customer.setName("javaeye");
  25. customerDAO.add(customer);
  26. Stringname=(String)jdbcTemplate.queryForObject("selectnamefromcustomerwhereid=?",newObject[]{customer.getId()},String.class);
  27.  
  28. assertEquals(customer.getName(),name);
  29. }
  30.  
  31. }

最后看看配置文件test.xml:

代码
 
  1. <?xmlversion="1.0"encoding="UTF-8"?>
  2. <!DOCTYPEbeansPUBLIC"-//SPRING//DTDBEAN//EN""http://www.springframework.org/dtd/spring-beans.dtd">
  3.  
  4. <!--
  5. -ApplicationcontextdefinitionforPetcliniconHibernate.
  6. -->
  7. <beans>
  8.  
  9. <!--=========================RESOURCEDEFINITIONS=========================-->
  10.  
  11. <!--Configurerthatreplaces${...}placeholderswithvaluesfromapropertiesfile-->
  12. <!--(inthiscase,JDBC-relatedsettingsforthedataSourcedefinitionbelow)-->
  13. <beanid="propertyConfigurer"class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
  14. <propertyname="location"><value>classpath:jdbc.properties</value></property>
  15. </bean>
  16.  
  17. <!--LocalDataSourcethatworksinanyenvironment-->
  18. <beanid="dataSource"class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  19. <propertyname="driverClassName"><value>${jdbc.driverClassName}</value></property>
  20. <propertyname="url"><value>${jdbc.url}</value></property>
  21. <propertyname="username"><value>${jdbc.username}</value></property>
  22. <propertyname="password"><value>${jdbc.password}</value></property>
  23. </bean>
  24.  
  25. <!--HibernateSessionFactory-->
  26. <beanid="sessionFactory"class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
  27. <propertyname="dataSource"><reflocal="dataSource"/></property>
  28. <propertyname="mappingResources">
  29. <value>rst/spring/mock/Customer.hbm.xml</value>
  30. </property>
  31. <propertyname="hibernateProperties">
  32. <props>
  33. <propkey="hibernate.dialect">${hibernate.dialect}</prop>
  34. <propkey="hibernate.show_sql">true</prop>
  35. </props>
  36. </property>
  37. </bean>
  38.  
  39. <!--TransactionmanagerforasingleHibernateSessionFactory(alternativetoJTA)-->
  40. <beanid="transactionManager"class="org.springframework.orm.hibernate.HibernateTransactionManager">
  41. <propertyname="sessionFactory"><reflocal="sessionFactory"/></property>
  42. </bean>
  43.  
  44. <beanid="hibernateTemplate"class="org.springframework.orm.hibernate.HibernateTemplate">
  45. <propertyname="sessionFactory"><reflocal="sessionFactory"/></property>
  46. </bean>
  47.  
  48. <beanid="customerDAO"class="rst.spring.mock.CustomerDAOHibernateImpl">
  49. <propertyname="hibernateTemplate"><reflocal="hibernateTemplate"/></property>
  50. </bean>
  51. </beans>

这个文件很简单,不要忘记transactionManager的配置,Test类会自动装配的。

运行之后,就可以看到应有的结果,并且数据库中不会有数据污染。这个过程主要是开始一个transaction,然后开始你的test方法,执行dao操作,执行sql查询验证结果,最后无论成功失败rollback transaction。

也许我孤陋寡闻,我是最近才发现的。
1.Spring Mock。
Mock主要用于测试Controller(or Action),Controller等同于一个Servlet,要测试它里面的方法,必须至少传入HttpRequest和HttpResponse
两个类的实例作为参数参数,直接new 一个HttpRequest是豪无意义的,必须使用mock。
Spring的mock那个包就提供了HttpRequest、HttpResponse、HttpSession的mock,测试controller时就可以直接new一个对象!
完整的测试代码Demo如下:

代码
 
  1. packageorg.ggyy.web.test;
  2.  
  3. importjunit.framework.TestCase;
  4.  
  5. importjava.io.File;
  6. importjava.io.IOException;
  7. importjava.util.List;
  8. importjava.util.Map;
  9.  
  10. importjavax.servlet.http.HttpServletRequest;
  11. importjavax.servlet.http.HttpServletResponse;
  12.  
  13. importjunit.framework.TestCase;
  14.  
  15. importorg.apache.commons.logging.Log;
  16. importorg.apache.commons.logging.LogFactory;
  17. importorg.ggyy.bo.Cat;
  18. importorg.ggyy.web.ctrl.CatController;
  19. importorg.springframework.mock.web.MockHttpServletRequest;
  20. importorg.springframework.mock.web.MockHttpServletResponse;
  21. importorg.springframework.mock.web.MockServletContext;
  22. importorg.springframework.web.context.support.XmlWebApplicationContext;
  23. importorg.springframework.web.servlet.ModelAndView;
  24.  
  25. publicclassListCatTestextendsTestCase{
  26. privatestaticLoglog=LogFactory.getLog(ListCatTest.class);
  27.  
  28. privateXmlWebApplicationContextctx;
  29.  
  30. publicvoidsetUp(){
  31. String[]paths={
  32. "file:/d:/eclipse/workspace/cat/WebRoot/WEB-INF/applicationContext.xml",
  33. "file:/d:/eclipse/workspace/cat/WebRoot/WEB-INF/pet-servlet.xml"};
  34. ctx=newXmlWebApplicationContext();
  35. ctx.setConfigLocations(paths);
  36. ctx.setServletContext(newMockServletContext(""));
  37. ctx.refresh();
  38. }
  39.  
  40. publicvoidtestGetUsers()throwsException{
  41. MockHttpServletRequestrequest=newMockHttpServletRequest();
  42. MockHttpServletResponseresponse=newMockHttpServletResponse();
  43. request.addParameter("parentId","2");
  44. CatControllerc=(CatController)ctx.getBean("catController");
  45. ModelAndViewmav=c.listCatHandler(request,response);
  46. Mapm=mav.getModel();
  47. }
  48. }


catController是MultiActionController,listCatHandler是其中的一个action。这里使用了绝对路径: "file:/d:/eclipse/workspace/cat/WebRoot/WEB-INF/pet-servlet.xml"。相对路径好像调试不出来。

2.基于Spring容器管理事务的测试--可以我表述不是很准确^_^
对于service层和dao的测试一般都是在实际的数据库中进行测试的,假如你不想使得测试对原来数据库造成任何影响,可以使用这种测试策略。整个测试是在Spring管理的事务中进行的,测试完毕,可以选择提交事务,也可以不提交事务,也就是说测试完后对原来的数据库的记录不造成任何影响。
这种测试策略最为诱人的还是:当测试不通过,也就是抛出异常时,事务可以自动回滚的!我以前测试前要清空数据库,测试不通过时测试用例后面的delete方法不能运行,我不得不手工的删除这些数据。
对于测试用例所依赖的bean,声明该bean的一个setter方法spring就可以自动的注入一个实例--很有意思,和ejb3.0类似。
我从pdf文档考下来一个demo供大家观赏:

代码
 
  1. publicabstractclassAbstractClinicTestsextendsAbstractTransactionalDataSourceSpringContextTests{
  2. protectedClinicclinic;
  3. publicvoidsetClinic(Clinicclinic){
  4. this.clinic=clinic;
  5. }
  6. publicvoidtestGetVets(){
  7. Collectionvets=this.clinic.getVets();
  8. assertEquals("JDBCquerymustshowthesamenumberofvets",
  9. jdbcTemplate.queryForInt("SELECTCOUNT(0)FROMVETS"),
  10. vets.size());
  11. Vetv1=(Vet)EntityUtils.getById(vets,Vet.class,2);
  12. assertEquals("Leary",v1.getLastName());
  13. assertEquals(1,v1.getNrOfSpecialties());
  14. assertEquals("radiology",((Specialty)v1.getSpecialties().get(0)).getName());
  15. Vetv2=(Vet)EntityUtils.getById(vets,Vet.class,3);
  16. assertEquals("Douglas",v2.getLastName());
  17. assertEquals(2,v2.getNrOfSpecialties());
  18. assertEquals("dentistry",((Specialty)v2.getSpecialties().get(0)).getName());
  19. assertEquals("surgery",((Specialty)v2.getSpecialties().get(1)).getName());
  20. }


上面的clinic实例是自动注入的,

 

本文地址:http://www.45fan.com/dnjc/69991.html
Tags: Spring 集成 dao
编辑:路饭网
关于我们 | 联系我们 | 友情链接 | 网站地图 | Sitemap | App | 返回顶部