锁定老帖子 主题:倒底该怎么写DAO的单元测试?
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (1)
|
|
---|---|
作者 | 正文 |
发表时间:2007-05-18
dao只测CRUD
如果有逻辑就在service中用mock来作DAO,否则你的测试太不稳定了。这异常还算好作如果有的异常是在两次插入中间产生的,你怎么用数据库来作? |
|
返回顶楼 | |
发表时间:2007-05-18
结合dbunit 和 spring的那个测试基类。 dbunit为你准备好数据。 数据是定义在xml文件中的
|
|
返回顶楼 | |
发表时间:2007-05-18
困惑多一: 新增一个用户后,需要调用一个方法getUserInfo来判断数据是否已经插入!!! UserDao.createUser(user); assertNotNull(user.getId()); 这样就行了 为什么要用getUserInfo() |
|
返回顶楼 | |
发表时间:2007-05-18
alin_ass 写道 我最近是生产用mysql,测试用hsqldb mem模式, 默认线程结束即销毁数据
e.g /** * @version 2007-5-9 * @author xalinx at gmail dot com * */ public class DalTestSupport extends TestSupport { @Before public void before() { dropAndCreateDb(); } @After public void after() { destoryConnection(); } private DataSource db1 = null; private Connection conn = null; private Statement stmt = null; private void dropAndCreateDb() { try { init(); drop(); createTables(); insertData(); } catch (Throwable e) { e.printStackTrace(); } } private void destoryConnection() { DbUtils.closeQuietly(conn, stmt); } private void init() throws SQLException { db1 = (DataSource) getBean("DB1"); conn = db1.getConnection(); stmt = conn.createStatement(); } protected User user1, user2; protected Group group1, group2; protected int userCount; protected int groupCount; private void insertData() throws SQLException { // insert group data String sql = "INSERT INTO USERGROUP(ID, NAME, MEMBERCOUNT) VALUES (1112, 'photo', 200);"; stmt.executeUpdate(sql); sql = "INSERT INTO USERGROUP(ID, NAME, MEMBERCOUNT) VALUES (1113, 'java', 100);"; stmt.executeUpdate(sql); group1 = new GroupImpl(); group1.setId(1112); group1.setName("photo"); group1.setMemberCount(200); group2 = new GroupImpl(); group2.setId(1113); group2.setName("java"); group2.setMemberCount(100); // insert user data sql = "INSERT INTO USER(ID, USERNAME, PASSWORD, NICKNAME, CITY, PROV, USERSTATUS, CREATETIME, MODIFYTIME) " + "VALUES (1001, 'xalinx@gmail.com', '888', 'nio', 'taizhou', 'zhejiang', 0, '2007-05-02 18:15:16', '2007-05-10 19:01:16');"; stmt.executeUpdate(sql); sql = "INSERT INTO USER(ID, USERNAME, PASSWORD, NICKNAME, CITY, PROV, USERSTATUS, CREATETIME, MODIFYTIME) " + "VALUES (1002, 'hsfaye@gmail.com', '888', 'faye', 'quzhou', 'zhejiang', 0, '2007-05-02 18:15:16', '2007-05-10 19:01:16');"; stmt.executeUpdate(sql); user1 = new UserImpl(); user1.setId(1001); user1.setUsername("xalinx@gmail.com"); user1.setPassword("888"); user1.setNickname("nio"); user1.setCity("taizhou"); user1.setProv("zhejiang"); Date createTime = new GregorianCalendar(2007, 4, 2, 18, 15, 16).getTime(); Date modifyTime = new GregorianCalendar(2007, 4, 10, 19, 1, 16).getTime(); user1.setCreateTime(createTime); user1.setModifyTime(modifyTime); user2 = new UserImpl(); user2.setId(1001); user2.setUsername("xalinx@gmail.com"); user2.setPassword("888"); user2.setNickname("nio"); user2.setCity("taizhou"); user2.setProv("zhejiang"); user2.setCreateTime(createTime); user2.setModifyTime(modifyTime); userCount = 2; groupCount = 2; } private void createTables() throws SQLException { String sql = "CREATE TABLE USERGROUP(ID BIGINT, NAME VARCHAR(254), MEMBERCOUNT INTEGER," + " CONSTRAINT PK_USERGROUP_ID PRIMARY KEY (ID), CONSTRAINT UK_USERGROUP_NAME UNIQUE (NAME));"; stmt.executeUpdate(sql); sql = "CREATE TABLE USER(ID BIGINT, USERNAME VARCHAR(254), PASSWORD VARCHAR(32), NICKNAME VARCHAR(32)," + " CITY VARCHAR(32), PROV VARCHAR(32), USERSTATUS BIGINT, CREATETIME DATETIME, MODIFYTIME DATETIME," + " CONSTRAINT PK_USER_ID PRIMARY KEY (ID), CONSTRAINT UK_USER_USERNAME UNIQUE (USERNAME)," + " CONSTRAINT UK_USER_NICKNAME UNIQUE (NICKNAME));"; stmt.executeUpdate(sql); } private void drop() throws SQLException { String sql = "DROP TABLE USERGROUP IF EXISTS"; stmt.executeUpdate(sql); sql = "DROP TABLE USER IF EXISTS"; stmt.executeUpdate(sql); user1 = null; user2 = null; userCount = 0; groupCount = 0; } } /** * @author alin [xalinx at gmail dot com] * @date 2007-5-7 */ public class UserDaoImplTest extends DalTestSupport { private UserDao userDao = (UserDaoImpl) getBean("userDao"); /** * Test method for {@link com.tworole.dal.dao.jdbc.UserDaoImpl#findCount()}. */ @Test public void findCount() { assertEquals(userCount, userDao.findCount()); } /** * Test method for * {@link com.tworole.dal.dao.jdbc.UserDaoImpl#findById(Long)}. */ @Test public void findById() { User u = userDao.findById(-1l); assertNull(u); u = userDao.findById(user1.getId()); assertEquals(u, user1); } /** * Test method for * {@link com.tworole.dal.dao.jdbc.UserDaoImpl#updateById(org.nanhill.commons.dbutil.builder.BeanMonitor)}. */ @Test public void testUpdateById() { String newNickName = "" + System.currentTimeMillis(); BeanMonitor<User> monitor = new BeanMonitor<User>(); User proxy = monitor.proxy(user1); proxy.setNickname(newNickName); userDao.updateById(monitor); User fetch = userDao.findById(user1.getId()); assertEquals(fetch.getNickname(), newNickName); } /** * Test method for * {@link com.tworole.dal.dao.jdbc.UserDaoImpl#deleteById(Long)}. */ @Test public void deleteById() { userDao.deleteById(user1.getId()); User u = userDao.findById(user1.getId()); assertNull(u); } } 这测试也太复杂了吧 连创建表都测试 |
|
返回顶楼 | |
发表时间:2007-05-18
addUserInfo之后调用getUserInfo来验证是否已经成功插入user,就算是测试方法依赖另外一个方法了吗?那么你的removeUser要是发生了异常,也同样会影响测试结果,保证测试的目的就行了吧。
如果是用的hibernate,倒是只要检查user.getId()非空就可以了。 |
|
返回顶楼 | |
发表时间:2007-05-18
有种东西叫做dbunit……
用dbunit,会在开始的时候准备好数据,再tearDown的时候默认的是删除。上面的GG也提到过,对于测试,也可以仿照RoR的做法,做一个测试用数据库,写一个测试的继承自TestCase,里面自动装载测试数据库。 |
|
返回顶楼 | |
发表时间:2007-05-18
把dao测试代码裹在一个事务里面,测试完成之后rollback.
这样既不会出现脏数据,也能够在测试当中测试所需要的动作并看到所作的变化。 好像很早以前就讨论过这个方法。 当然,最好的办法还是使用单独的数据库。但是即使在这种情形下,前面的办法也很有用。 |
|
返回顶楼 | |
发表时间:2007-05-19
主要是业务没分层太复杂 了
|
|
返回顶楼 | |
发表时间:2007-05-21
貌似可以使用DBUnit,不过我没用过
|
|
返回顶楼 | |
发表时间:2007-05-21
想怎么写就怎么写吧,
能做到没有软件没有bug就行 每个人的习惯不同,有些人喜欢mock,有的人喜欢准备一个简单的数据库(java内存数据库)有的人喜欢。。。。 而我比较喜欢真正的写到数据库里面 |
|
返回顶楼 | |