花钱的年华

--今天开始成为主站

用户操作
[即时聊天] [发私信] [加为好友]
江南白衣ID:calvinxiu
691415次访问,排名53好友0人,关注者38
calvinxiu的文章
原创 161 篇
翻译 0 篇
转载 0 篇
评论 646 篇
江南白衣的公告

肖桦,江南白衣,
开源项目SpringSide
春天的旁边
发起者

最近评论
calvinxiu:
发版本最痛苦的事情,就是刚发完之后忽然又有了一个比较重要的更新。

推荐大家下载3.0.3.1 (2mb)

1.简化了目录结构,感觉又清爽了不少。
2.消除了最后一块需要逐个Class写配置文件的地方(applicationContext.xml中的sessionFactory的mapping class)。
dreaming:恭喜~
hongyi:还是一头雾水,郁闷,为啥有这么多东东,叫人头大
suncheng_hong:用过appfuse,但springside还没有尝试过。
suncheng_hong:很想尝试一下。
文章分类
    收藏
      相册
      Blog用图
      Friends
      @_@
      Anders小明
      buaawhl
      cac
      canonical
      cctvx1
      david.turing
      femto
      g9
      JohnsonQu
      Michael Chen
      Raimundox
      robbin
      SimonLei
      totodo
      wuyu
      周爱民
      孟岩
      差沙
      庄表伟
      落魄的程序员
      透明
      郁也风
      铁手
      银狐999
      飞云小侠
      存档
      订阅我的博客
      XML聚合  FeedSky
      订阅到鲜果
      订阅到Google
      订阅到抓虾
      订阅到BlogLines
      订阅到Yahoo
      订阅到GouGou
      订阅到飞鸽
      订阅到Rojo
      订阅到newsgator
      订阅到netvibes

      原创 Spring下的Unit Test Notes 2nd收藏

      新一篇: Spring 下透明的让POJO 变为支持JMX的MBean | 旧一篇: 写Eclipse插件,告别纯Ant时代

           作者:江南白衣  

           注重实效的TDD的确能加快,而不是拖慢开发的进度(片面的追求覆盖率的全面UnitTest不在此列)
            一,可以实现真正分层开发。
            二,不需要依赖和频繁重启Web Container。
            三,手工测试总不免改动数据库,如何把数据库恢复到测试前的状态是件伤脑筋的事情。而Unit Test可以使用自动Rollback机制,巧妙的解决了这件事情。

            Spring 下的Unit Test主要关注三个方面:
             1. bean的依赖注入
             2. 事务控制,Open Session in Test 及默认回滚
             3. 脱离WebContainer对控制层的测试
            

         1.bean的依赖注入 
        能不依靠WebContainer来完成ApplicationContext的建立与POJO的依赖注入一向是Spring的得意之处。

      String[] paths = { "classpath:applicationContext*.xml" };
      ApplicationContext ctx 
      =new ClassPathXmlApplicationContext(paths);
      UserDAO dao 
      = (UserDAO) ctx.getBean("userDAO");

          如果你连这也觉得麻烦,那么只要你的testCase继承于Spring-mock.jar里的AbstractDependencyInjectionSpringContextTests,实现public String[] getConfigLocations()函数, 并显式写一些需要注入的变量的setter函数。
          注:因为是AutoWire的,变量名必须等于Spring  context文件里bean的id。

      2.Open Session in Test 及自动Rollback
           又是来自Spring这个神奇国度的东西, 你可以让testCase继承于AbstractTransactionalDataSourceSpringContextTests,就可以做到Open Session in Test ,解决Hibernate的lazy-load问题;而且接管原来的DAO里的事务控制定义,通过setDefaultRollback(boolean)方法控制最后回滚还是提交,如果默认为回滚,则测试产生数据变动不会影响数据库内数据。
       
          如果不能继承于这个基类,可以自己简单编写,代码是这样的:

         protected PlatformTransactionManager transactionManager;
         
      protected TransactionStatus transactionStatus;
         
      protected boolean defaultRollback = true;
         
      public void setUp()
         {
              transactionManager 
      = (PlatformTransactionManager) ctx.getBean("transactionManager");
              transactionStatus 
      = transactionManager.getTransaction(new DefaultTransactionDefinition());
         }
         
      public void tearDown()
         {
              
      if (defaultRollback)
                  transactionManager.rollback(
      this.transactionStatus);
              
      else
                 transactionManager.commit(
      this.transactionStatus);
          }

        (注,hibernate太奸诈了,如果全部默认回滚,只会在session里干活,一点不写数据库,达不到完全的测试效果。)

      BTW.AbstractTransactionalDataSourceSpringContextTests 还通过注入的DataSource创建了一个JDBCTemplate 对象,可以跑SQL帮忙核对Hibernate的结果,但要注意两者的事务。

      3.Controller层的Unit Test

      controller层靠Spring提供的MockHttpServletRequest和Response来模拟真实的servlet环境,并且spring 2.0了加了一个AbstractModelAndViewTests,提供一些检测返回值的utils函数。

          protected XmlWebApplicationContext ctx;
          
      protected MockHttpServletRequest request = new MockHttpServletRequest("GET""");
          
      protected MockHttpServletResponse response = new MockHttpServletResponse();
          
      protected Controller controller = null;
          
      protected ModelAndView mv = null;
         
      public void setUp()
         {
              String[] paths 
      = {"applicationContext*.xml","myappfuse-servlet.xml"};
              ctx 
      = new XmlWebApplicationContext();
              ctx.setConfigLocations(paths);
              ctx.setServletContext(
      new MockServletContext(""));        ctx.refresh();
              controller 
      = (CustomerController) ctx.getBean("customerController");
              
      //再加上前文的事务控制的代码
         }
          
      public void testCustomerList() throws Exception
          {
              request.setRequestURI(
      "/customer.do");
              request.addParameter(
      "action""listView");
              mv 
      = controller.handleRequest(request, response);
              assertModelAttributeAvailable(mv, "customers");

          }

        
      4.进一步简化
      一来这两个基类的名字都太长了。
      二来有一些公共的context文件的定义。

      所以可以再抽象了几个基类,分别是DAOTestCase,ControllerTestCase。

      5. EasyMock
         MockObject是一样彻底分层开发的好东西,而且使用上没什么难度。而且已不再存在只支持接口不支持Class的限制。
        

      //设定BookManager MockObject
              bookManagerMockControl = MockClassControl.createControl(BookManager.class);
              bookManagerMock 
      = (BookManager) bookManagerMockControl.getMock();
              controller.setBookManager(bookManagerMock);
              
      //录制getAllBook()和getCategorys方法的期望值
              bookManagerMock.getAllBook();
              bookManagerMockControl.setReturnValue(
      new ArrayList());
              bookManagerMockControl.replay();
               
      //执行操作
              mv = controller.handleRequest(request, response);
      //验证结果          
              assertModelAttributeAvailable(mv, "books");

         Easy Mock VS JMock:

          JMock 要求TestCase继承于MockObjectTestCase太霸道了。妨碍了我继承于Spring2.0的ModelAndViewTestCase和使用MockDao,RealDao并行的继承体系。因此采用没那么霸道的easyMock。

         另外,easyMock的脚本录制虽不如jmock那么优美,但胜在简短易读。jmock那句太长了 。


      6. 显示层测试
      还有,显示层至今没有什么好的UnitTest方法,无论是不成才的httpUnit们还是笨重的GUI test工具。Appfuse一直用的那个ThoughtWork那个SeleniumJ3Unit的效果不知如何, 其中J3Unit号称支持prototype

      发表于 @ 2005年07月27日 15:21:00|评论(loading...)|编辑

      新一篇: Spring 下透明的让POJO 变为支持JMX的MBean | 旧一篇: 写Eclipse插件,告别纯Ant时代

      评论:没有评论。

      发表评论  


      登录
      Csdn Blog version 3.1a
      Copyright © 江南白衣