单元测试实践之设计的常见分层和DAO的测试

Malak ·
更新时间:2024-09-20
· 824 次阅读

  我做过的项目不多。也几个。做项目的经历是个学习的过程。

  第一个项目,纯Jsp,没有任何的java类,当时觉得好郁闷啊。做久了,根本找不到北。

  第2个项目:开始会用些javabean来做了。但是还是一个字好乱。

  第3个项目:开始使用hibernate, 只是对数据库层做了些简单的封装,修改起来比较好了点

  第4个项目:研究Webwork+spring+hibernate。终于实现了所谓的MVC了。哈哈,该起程序来终于开始有点爽了。

  第5个项目: 开始引入了单元测试,现在还在很懵懂在学习中,为了更好的测试,我们开始努力写出更高质量的代码。所以对软件的分层更细致了些。

  我们可以从测试来分出上的设计的好坏。

  1,纯jsp,根本无从单元测试,我想是那些大牛们也很难写出这样的测试代码吧

  2,对于纯粹只有get/set的javabean而言,我想应该是没有必要做单元测试的。如果有逻辑代码的话,测试起来也是相当困难的,因为你不知道里面的逻辑代码跟多少个类大了交道,你会为了测试这段代码,建立相关的环境,比如启动EJB,Web容器等。跟难预料的是,跟你耦合的类未必是正确的,其实你的测试代码跟你的javabean逻辑是对的,但是因为你引用的类(也是耦合类)的逻辑是错误的,这将导致你的测试是个红色,“真的很抱歉,其实我也不想这样的,单元测试说”。 这样足以证明是你的设计问题了。并不是单元测试的问题。所以说第个项目测试是很难测是的。只是比不能测试好一点点。

  3,至于第3个跟第2个差不多。

  4,第4个由于对每个层做了细致设计,所以设计测试代码容易点,而且可以通过easymock等工具进行分层测试,这样可以做到更细粒度的测试,对测试覆盖率也是很有帮助的。下面我将主要通过第4个项目的用户注册例子来讲单元测试的各个方面。

  来看下流程图。

  可以很清楚的知道,没一层做些什么工作,接下的文章,我将会根据我的设计习惯,一一给出他们相应的测试代码。希望高手们指教。

  我不会绘制UML图,所以只好手工来画,可惜手机像素不高,所以。。。。

测试DAO不如连数据库一起测试吧。因为DAO测试的目的不是DAO接口实现对不对,而是测试是否如你预期的发送了SQL,如你预期的返回了结果集。这个时候你Mock之后,测试没有意义了。

但是数据库的测试毕竟比较特殊,记住测试的目的是确保你的代码质量,如果你确定你的这样测没问题了,那无话可说,否则尽量多的测试。

事实上,原始的单元测试(plain testcase)是用来测方法,测业务逻辑的,如果有逻辑测,没逻辑不用测了,同样的道理,相信你不会去测一个bean的get/set方法吧。

记住你测试的目的和动机,如果你认为测试dao层是为了测你的逻辑(你确定你的dao的实现代码是否真的存在逻辑),那你mock吧,但是,我 们更相信,我们测DAO层,更应该是测访问数据库的情况,你如连接,sql是否正确,sequence是否正确等,而这些你必须要真正的连接数据库,也因 此,我们一般都是直接访问数据库来测试的,当然,如果可能你可以采用内存库。

事实上,我们对dao的测试,一般都进行所谓的的集成单元测试。我认为,你应该确定好你的测试策略,然后在去采用相应的测试方法。我在目前的开发中是采用这样的方式测的。

上面两个大哥都建议测试DAO的时候还是连接数据库为好。

但个人认为上面两个大哥的单元测试以非纯正的单元测试了,而是集成单元测试。

其实说白了,测试这东西只是为了项目更好,更快的完成。至于是否要求纯单元,或者是集成单元测试,则看各位的需要,如果觉得集成单元测试对项目有帮助,那用吧,现在发现对这个已经没有明显的界限了。

不理会它了,现在回归到我们用户注册的例子。

    1. public interface IAccountDao extends IBaseDao {        2.     public Account findAccountById(String id);        3.     public Account findAccounByName(String name);        4. }  

实际实现代码

    package org.wuhua.dao.impl;            import java.util.List;            import org.wuhua.dao.IAccountDao;      import org.wuhua.model.Account;            public class AccountDao extends BaseDao implements IAccountDao {        public Account findAccountById(String id) {              return (Account) this.getHibernateTemplate().get(Account.class, id) ;          }                public Account findAccounByName(String name) {              List l = this.getHibernateTemplate().find("from Account as a where a.name=?", name);              if(l != null && l.size() >=1)                  return (Account) l.get(0);              else                   return null;          }      } 

    package org.wuhua.dao;            import java.util.ArrayList;      import java.util.List;            import junit.framework.Assert;      import junit.framework.TestCase;            import org.easymock.MockControl;      import org.easymock.classextension.MockClassControl;      import org.springframework.orm.hibernate3.HibernateTemplate;      import org.wuhua.dao.impl.AccountDao;      import org.wuhua.model.Account;            public class AccountDaoTest extends TestCase {                    private AccountDao accountDao;          private org.springframework.orm.hibernate3.HibernateTemplate ht;          private MockControl control;                protected void setUp() throws Exception {              control = MockClassControl.createControl(HibernateTemplate.class);              ht = (HibernateTemplate) control.getMock();              accountDao = new AccountDao();              accountDao.setHibernateTemplate(ht);          }                protected void tearDown() throws Exception {                         }                    public void testFindAccountById(){              Account a = new Account("wuhua");              a.setId("10");                               ht.get(Account.class, a.getId());                            control.setReturnValue(a);                            control.replay();                            Account result =   accountDao.findAccountById(a.getId());                            assertNotNull(result);                    Assert.assertEquals(a.getId(),result.getId());              Assert.assertEquals(a, result);                            control.verify();                        }                    public void testFindAccountByName(){              Account a = new Account("wuhua");                                 ht.find("from Account as a where a.name=?", a.getName());              List l = new ArrayList();              l.add(a);              control.setReturnValue(l);                            control.replay();                            Account result =  accountDao.findAccounByName(a.getName());                    Assert.assertEquals(a.getId(),result.getId());              Assert.assertEquals(a, result);                            control.verify();                        }      } 



单元测试 单元 dao 测试

需要 登录 后方可回复, 如果你还没有账号请 注册新账号
相关文章