论坛首页 Java企业应用论坛

倒底该怎么写DAO的单元测试?

浏览 19531 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (1)
作者 正文
   发表时间:2007-05-18  
dao只测CRUD
如果有逻辑就在service中用mock来作DAO,否则你的测试太不稳定了。这异常还算好作如果有的异常是在两次插入中间产生的,你怎么用数据库来作?
0 请登录后投票
   发表时间:2007-05-18  
结合dbunit 和  spring的那个测试基类。  dbunit为你准备好数据。 数据是定义在xml文件中的
0 请登录后投票
   发表时间:2007-05-18  
困惑多一: 
新增一个用户后,需要调用一个方法getUserInfo来判断数据是否已经插入!!!

UserDao.createUser(user);
assertNotNull(user.getId());

这样就行了 为什么要用getUserInfo()
0 请登录后投票
   发表时间: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);
	}

}

这测试也太复杂了吧 连创建表都测试
0 请登录后投票
   发表时间:2007-05-18  
addUserInfo之后调用getUserInfo来验证是否已经成功插入user,就算是测试方法依赖另外一个方法了吗?那么你的removeUser要是发生了异常,也同样会影响测试结果,保证测试的目的就行了吧。
如果是用的hibernate,倒是只要检查user.getId()非空就可以了。
0 请登录后投票
   发表时间:2007-05-18  
有种东西叫做dbunit……
用dbunit,会在开始的时候准备好数据,再tearDown的时候默认的是删除。上面的GG也提到过,对于测试,也可以仿照RoR的做法,做一个测试用数据库,写一个测试的继承自TestCase,里面自动装载测试数据库。
0 请登录后投票
   发表时间:2007-05-18  
把dao测试代码裹在一个事务里面,测试完成之后rollback.
这样既不会出现脏数据,也能够在测试当中测试所需要的动作并看到所作的变化。
好像很早以前就讨论过这个方法。
当然,最好的办法还是使用单独的数据库。但是即使在这种情形下,前面的办法也很有用。
0 请登录后投票
   发表时间:2007-05-19  
主要是业务没分层太复杂 了
0 请登录后投票
   发表时间:2007-05-21  
貌似可以使用DBUnit,不过我没用过
0 请登录后投票
   发表时间:2007-05-21  
想怎么写就怎么写吧,
能做到没有软件没有bug就行
每个人的习惯不同,有些人喜欢mock,有的人喜欢准备一个简单的数据库(java内存数据库)有的人喜欢。。。。
而我比较喜欢真正的写到数据库里面
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics