发表于: 2017-04-26 22:41:34

1 1611


Task1的第五天


今日计划

  1. 理解DAO单元测试

今日完成

了解如何做DAO层的单元测试

今天花了很多时间了解如何做DAO层的单元测试,不是方法不会,而是目的不清晰。本来日报里的问题都写好了,然后**暗灭大人暗灭大人在群里回复我的问题了……

先插入,再更新,再查询,再删除,再查询的顺序写一个测试方法测试CRUD就够了,测试完成后就吧JUnit代码注释掉,应该是为了防止测试代码频繁访问数据库。

测试代码

package com.semonx.jnshu.dao.impl;

import com.semonx.jnshu.bean.StudentBean;
import com.semonx.jnshu.config.JNShuConfig;
import com.semonx.jnshu.dao.StudentDao;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import static org.junit.Assert.*;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = JNShuConfig.class)
public class StudentDaoImplTest {
   @Autowired
   private StudentDao dao;

   @Test
   public void testCRUD() {
       // 插入的数据
       StudentBean bean = new StudentBean();
       bean.setName("朱重八");
       bean.setQq("12345678");
       bean.setProfession("JAVA工程师");
       bean.setJoin_date(1491753600000L);
       bean.setSchool("清华大学");
       bean.setOnline_id("1000");
       bean.setDaily_url("http://www.jnshu.com/daily/18132?uid=10224");
       bean.setDeclaration("如果我不能在IT 特训营拼尽全力,为自己以后的修行路上打好基础,就让我永远追不到喜欢的人,给不了她想要的生活!");
       bean.setIntroducer("");
       bean.setReferee("");
       bean.setCounselor("");
       bean.setDescription("从知乎暗灭了解 到的修真院\n" +
               "\n" +
               "来的目的:打好编程基础,锻炼编程效率,思维。");
       bean.setCity("北京");
       bean.setReview("待审核");

       final String onlineId = "1000";
       final String updatedName = "小九九";
       // 先插入一条数据
       dao.addStudent(bean);
       // 更新刚才插入的数据
       bean.setName(updatedName);
       dao.updateStudentByOnlineId(onlineId, bean);
       // 读出刚才更改的数据,通过断言进行比较
       StudentBean updatedBean = dao.getStudentByOnlineId(onlineId);
       // 删除最开始插入的数据
       dao.deleteStudentByOnlineId(onlineId);
       // 查询,发现已经查询不到被删除的数据
       StudentBean deletedBean = dao.getStudentByOnlineId(onlineId);

       // 确认插入,更新,查询功能正常
       assertEquals(updatedName, updatedBean.getName());
       assertEquals(bean.getQq(), updatedBean.getQq());
       assertEquals(bean.getProfession(), updatedBean.getProfession());
       assertEquals(bean.getJoin_date(), updatedBean.getJoin_date());
       assertEquals(bean.getSchool(), updatedBean.getSchool());
       assertEquals(bean.getOnline_id(), updatedBean.getOnline_id());
       assertEquals(bean.getDaily_url(), updatedBean.getDaily_url());
       assertEquals(bean.getDeclaration(), updatedBean.getDeclaration());
       assertEquals(bean.getIntroducer(), updatedBean.getIntroducer());
       assertEquals(bean.getReferee(), updatedBean.getReferee());
       assertEquals(bean.getCounselor(), updatedBean.getCounselor());
       assertEquals(bean.getDescription(), updatedBean.getDescription());
       assertEquals(bean.getCity(), updatedBean.getCity());
       assertEquals(bean.getReview(), updatedBean.getReview());
       // 确认删除,查询功能正常
       assertNull(deletedBean);
   }

}

为了保证数据的干净(测试完成后数据库数据不会发生改变),在测试方法中完整保留了先插入,再更新,再查询,再删除,再查询的流程,将断言放到了最后。

另外,我感觉一条一条的填充字段,一条一条地断言,导致代码很膨胀啊。请问师兄,有什么优雅的方法吗?

明日计划

明天要忙点毕业的事,请假一天

问题总结

暗灭老大在群里给了解决方案后,问题算是解决了,不过写都写了,就放出来记录下我的纠结历程吧。

今天取消了完善测试的计划,原因是不太明白单元测试如何设计。JUnit的基本功能我是会用的,参见昨天日报的测试部分。但是怎么设计就有些矛盾了,矛盾点如下:

  1. 单元测试应该访问数据库吗?或者访问数据库的还是单元测试吗?
  2. CRUD中的CUD都会使数据表发生改变,在做DAO层的单元测试的时候,这几个方法就会互相依赖。
  3. 比如,我要测试C(插入),我调用(删除)操作。这时插入的测试就依赖了删除操作。插入一条数据,当测试方法结束后,我要把数据库还原到之前的状态,我就要删除掉这一条数据,这是我就要用D(删除)操作。这时插入的测试就依赖了删除操作。
  4. 反之,测试删除前要保证数据库中至少有一条数据,删除完成后,还要还原数据库,依赖了插入操作。
  5. 更尴尬的是,U(更新)操作后,要想还原,就要使用更新操作……
  6. 这个时候他们都依赖R(查询)操作就真心不算什么了
  7. 或者,DAO层的单元测试根本不是这样做的?百度到的单元测试众说纷纭,很乱。百度到一篇讲TDD如何好的,接着就又看到一篇说MVC和TDD矛盾的,天……
  8. 我这点经验根本没法辨别这些文章啊,望师兄指条明路。



返回列表 返回列表
评论

    分享到