不知道大家做Junit测试时对于数据库的操作都是怎么进行验证的。我说下我们项目里遇到的一些问题。
1、对于查询功能的Dao函数
   Dao返回值:返回List,如果查询到数据时,List里面包含多个JavaBean。JavaBean里的属性的格式包含基本类型、数组类型、List型、Map型、其他JavaBean。
   正常的验证代码是:
   List list = Dao.Search();
   assertEquals(1, list.size());
   XXXVO vo = list.get(index);
   assertEquals("0001", vo.getNo());
   assertEquals("Name", vo.getName());
   问题:需要验证的JavaBean里的属性太多,太复杂。要写很多assert代码。数据写死在测试代码里了,更换一组测试数据时需要从新写Junit代码。
   期望的解决方法:预期的数据通过一种格式保存在XML文件中,根据XML里的数据对返回的List进行验证。
                   例:assertObject("result_01.xml", list); 
                注:所有返回的JavaBean都没有实现Equals方法。所以不能整个对象比较。
2、更新和插入动作的Dao函数
   正常的验证方式是:执行Dao的方法后,执行一段查询,将Dao插入的数据查询出来然后逐一验证。
   问题:需要写的代码太多,不好维护。
   期望的解决方法:将期望Dao执行后的数据表状态,预先写到一个XML文件中。Dao执行之后,根据XML文件的内容与数据库中表的内容进行比较。
   新的问题:一些表中的字段(主要是主键)是通过数据库中的SEQUENCES对象的值插入的(自动增长字段),在Dao执行之前无法预期其值。因为是多人进行测试,
            所以SEQUENCES对象是多人在使用,所以无法预期SEQUENCES的使用状态。不知道我描述的是否清楚,请高手来帮忙提出一些解决方案。最好是有实现的方案。也可以说说你们做项目时的测试方法。谢谢!

解决方案 »

  1.   

    首先,我们现在采用spring-mock!
    1,查询不建议写单元测试的,即使写,首先你要做insert吧,然后才能查询,insert后取出id,然后靠这个id去查,然后assert关键字段就行;
    2,因为数据可以自动回滚,所以不存在你那个问题;另外:测试数据准备很重要,可以抽象出来公用的数据准备类,也可以写成xml!
      

  2.   

    同问哈.
    另外, 最近看到Eclipse 里面有个DBUnit 的东西, 好像是做数据库的单元测试的, 但是还没有用过.
      

  3.   

    spring-mock是用在Spring项目里吧,我们这目前还没用过。
    1,单元测试是项目要求的,所以我们必须写,包括查询的Case。目前我们的测试数据是通过DBUnit的XML文件配置的,所以对于查询Case检索结果我们是可以预期的。正常的验证写法“assertEquals("0001", vo.getNo());” 我们都知道,现在的问题是这样的验证语句太多了,一个查询会返回很多表的很多字段。这样我们就得写好夺得assertEquals语句。特别是返回多条的情况,因为验证代码不能循环,所以只能一条一条的写。换一组测试数据的话需要该好多的语句。
    2,数据回滚?那我还怎么验证我的Dao有没有插入数据呢。我需要执行Dao向数据库插入数据,然后我要检索出数据,一个字段一个字段的验证其正确性。问题还是要写得验证代码太多。想寻求一种简化代码量的方法
      

  4.   

    DBUnit是很好。它的主要功能是提供测试Case执行之前和之后的对数据库的一些操作。我们项目里用的就是DBUnit
      

  5.   

    我说的自动回滚,是发生在验证后的!你对单元测试的理解有问题,并不是为了验证每一条数据,每一个字段!单元测试的原则:单元测试必须是可重复的,无论是在软件修改,或是移植到新的运行环境的过程中,当然也包括你的所谓的数据修改!针对你们的做法,我提几点:
    1,“assertEquals("0001", vo.getNo());” 那你只能把0001转成中间变量了,不能直接写死数据;
    2,尽可能的抽象,泛化!
      

  6.   

    不知道是我没理解你的说法还是你没理解我的问题。感觉好像对不上呢。
    我们验证每一条数据和每一个字段是为了验证Dao最终生成的Insert语句的正确性。当然可以Mock一些Jdbc的类来验证Dao的正确。但那样做对于我们难度太高,我们还是以验证数据库中的数据来验证Dao的正确性。你可以说说你们做得项目怎么验证Dao。我们的单体测试代码肯定是可重复使用反复测试的,我从没说过只在特定环境下,进行一次性的测试阿。你的提议我很占同。我现在的问题也是不想写“assertEquals("0001", vo.getNo());” 这样的代码。想找出一个方案来代替这些验证代码。
    数据我想放到XML中。想让代码自动对XML的数据与查询返回的数据进行验证。
      

  7.   

    我们现在不存在dao的概念!
    DDD开发模式!数据我想放到XML中。想让代码自动对XML的数据与查询返回的数据进行验证。恩,就好好考虑下这个吧!
      

  8.   


    网上的例子太多了,在百度里搜索DBUnit就会找到很多。http://blog.csdn.net/tianyawudie/archive/2008/05/07/2409500.aspx
      

  9.   

    DDD开发模式? 重来没听说过。
    存放数据的XML格式我已经想好,帮忙看一下可不可行,有没有问题。
    XML文件是Java Properties 的保存格式。如下:<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
    <properties>
      <!-- []代表数组或是List对象,因为Dao返回的是List所以前面加[0]代表List里的第一个对象的no属性值是12345 -->
      <entry key="[0].no">12345</entry>
      <!-- List里的第一个对象的name属性值是AAA -->
      <entry key="[0].name">AAA</entry>
      <!-- JavaBean中包含另一个Bean的情况属性中间用.分隔。这句代表List中的第二个对象的address属性的addressCd属性是0005 -->
      <entry key="[1].address.addressCd">0005</entry>
      <!-- []也可以放到属性后面,代表home属性是一个List或数组 -->
      <entry key="[0].home[0]">kkk</entry>
      <!-- ()代表Map之类的对象,通过Key取得对象,()中的内容为Key -->
      <entry key="[0].sss(key).pro1">2234</entry>
    </properties>
      

  10.   

    可以使用dbunit的这个方法来做验证:
    Assertion.assertEquals(ITable, ITable);
    你可以尝试一下。