发表于: 2017-04-26 22:41:34
1 1611
Task1的第五天
今日计划
- 理解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的基本功能我是会用的,参见昨天日报的测试部分。但是怎么设计就有些矛盾了,矛盾点如下:
- 单元测试应该访问数据库吗?或者访问数据库的还是单元测试吗?
CRUD
中的CUD
都会使数据表发生改变,在做DAO层的单元测试的时候,这几个方法就会互相依赖。- 比如,我要测试
C
(插入),我调用(删除)操作。这时插入的测试就依赖了删除操作。插入一条数据,当测试方法结束后,我要把数据库还原到之前的状态,我就要删除掉这一条数据,这是我就要用D
(删除)操作。这时插入的测试就依赖了删除操作。- 反之,测试删除前要保证数据库中至少有一条数据,删除完成后,还要还原数据库,依赖了插入操作。
- 更尴尬的是,
U
(更新)操作后,要想还原,就要使用更新操作……- 这个时候他们都依赖
R
(查询)操作就真心不算什么了- 或者,DAO层的单元测试根本不是这样做的?百度到的单元测试众说纷纭,很乱。百度到一篇讲TDD如何好的,接着就又看到一篇说MVC和TDD矛盾的,天……
- 我这点经验根本没法辨别这些文章啊,望师兄指条明路。
评论