日期:2014-05-16  浏览次数:20547 次

spring-mock + dbutil 用来测试数据库操作
大概流程:
1.用dbunit创建初始的测试数据。
2.用spring-mock 维护测试过程中的数据会滚,这样可以保证测试后数据库保持原状态。
3.用junit架构测试。
4.用dbunit销毁初始测试数据。

对Dao进行单元测试,一般有两种思路。一是Mock,对使用的底层API进行Mock,比如Hibernate和JDBC接口,判断接口有没有正确调用,另一种是实际访问数据库,判断数据库有没有正确读写。更多的情况下,我更倾向于后者,因为在使用ORM工具或者jdbcTemplate的情况下,dao一般只有简单的几行代码,没有复杂的逻辑,Mock测试一般没有什么意义,我们更关心的是,Hibernate mapping是否正确,ibatis sql是否正确等,所以实际读写数据库才能真正判断一个dao是否正确,这也是我们关心的测试内容。
package com.test.dbunit.dao;

import javax.sql.DataSource;

import org.dbunit.Assertion;
import org.dbunit.database.DatabaseConnection;
import org.dbunit.database.IDatabaseConnection;
import org.dbunit.database.QueryDataSet;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.xml.FlatXmlDataSet;
import org.dbunit.operation.DatabaseOperation;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
import org.springframework.test.context.transaction.TransactionConfiguration;

import com.test.dbunit.entity.User;


@ContextConfiguration(locations = { "classpath:testApplicationContext.xml" })
@TransactionConfiguration(defaultRollback = true)
public class UserDaoTest extends AbstractTransactionalJUnit4SpringContextTests {
	@Autowired
	private UserDao userDao;

	@Autowired
	private DataSource dataSource;

	private IDatabaseConnection conn;

	@Before
	public void initDbunit() throws Exception {
		conn = new DatabaseConnection(DataSourceUtils.getConnection(dataSource));
	}

	@Test
	public void saveUser() throws Exception {
		User user = new User();
		user.setNick("user001");
		user.setPassword("password001");
		userDao.save(user);

		QueryDataSet actual = new QueryDataSet(conn);
		actual.addTable("user",
				"select * from user where user.nick = 'user001'");

		IDataSet expected = new FlatXmlDataSet(new ClassPathResource(
				"com/taobao/dbunit/dao/user001.xml").getFile());

		Assertion.assertEquals(expected, actual);
	}

	@Test
	public void updateUser() throws Exception {

		IDataSet origen = new FlatXmlDataSet(new ClassPathResource(
				"com/taobao/dbunit/dao/user001.xml").getFile());

		DatabaseOperation.INSERT.execute(conn, origen);

		User user = new User();
		user.setNick("user001");
		user.setPassword("password002");
		userDao.update(user);

		QueryDataSet actual = new QueryDataSet(conn);
		actual.addTable("user",
				"select * from user where user.nick = 'user001'");

		IDataSet expected = new FlatXmlDataSet(new ClassPathResource(
				"com/taobao/dbunit/dao/user001_updated.xml").getFile());

		Assertion.assertEquals(expected, actual);
	}

	@Test
	public void removeUser() throws Exception {
		IDataSet origen = new FlatXmlDataSet(new ClassPathResource(
				"com/taobao/dbunit/dao/user001.xml").getFile());
		DatabaseOperation.INSERT.execute(conn, origen);

		userDao.remove("user001");

		QueryDataSet actual = new QueryDataSet(conn);
		actual.addTable("user", "select * from user where nick = 'user001'");

		Assert.assertEquals(0, actual.getTable("user").getRowCount());
		
	}
	
	@Test
	public void findUser() throws Exception {
		IDataSet data = new FlatXmlDataSet(new ClassPathResource(
				"com/taobao/dbunit/dao/user001.xml").getFile());
		DatabaseOperation.INSERT.execute(conn, data);

		
		User user = userDao.getUserByNick("user001");

		Assert.assertEquals("password001", user.getPassword());
	}

}


package com.test.dbunit.dao.impl;   
  
import java.sql.ResultSet;   
import java.sql.SQLException;   
  
import org.springframework.jdbc.core.RowMapper;   
  
import com.test.dbunit.dao.UserDao;   
import com.test.dbunit.entity.User;   
  
public class DefaultUserDao ex