DBUnit是JUnit的一个扩展,对于数据库驱动的项目而言(基本上所有的Web项目都是数据库驱动的),对于服务层的单元测试非常麻烦,因为 不能保证每次测试时数据库都是同一个状态,所以开发者不敢写断言(assertEquals())。我个人也是因为这个原因所以对驱动测试开发总是敬而远 之。
有了DBUnit,一切都变了,DBUnit的目的就是在每个单元测试运行之前将数据库初始化成一个预定义的状态,以保证单元测试时的断言不会因为 数据库状态发生了变化而失败,同时可以解决前一个单元测试失败导致对数据库的操作未按照测试用例执行而影响后一个单元测试的问题。
为了提高单元测试效率和简化单元测试工作,下面介绍DBUnit与H2内存数据库结合作为单元测试,首先安装H2,详细请查看http://www.h2database.com/html/main.html
下面详细贴一下代码说明:
Maven依赖(当然可以依赖mysql)
<dependency> <groupId>org.dbunit</groupId> <artifactId>dbunit</artifactId> <version>2.4.6</version> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>1.3.171</version> </dependency>
Maven插件
<!-- maven sql 插件 --> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>sql-maven-plugin</artifactId> <version>1.3</version> <!-- <dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.9</version> </dependency> </dependencies> <configuration> <driver>com.mysql.jdbc.Driver</driver> <url>jdbc:mysql://127.0.0.1:3306/dbunitdemo</url> <username>root</username> <password>123</password> <srcFiles> <srcFile>src/main/sql/dbunitdemo.sql</srcFile> </srcFiles> </configuration> --> <dependencies> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>1.3.171</version> </dependency> </dependencies> <configuration> <driver>org.h2.Driver</driver> <url>jdbc:h2:~/dbunitdemo</url> <username>sa</username> <password></password> <srcFiles> <srcFile>src/main/sql/dbunitdemo.sql</srcFile> </srcFiles> </configuration> </plugin>
编写Dao层,与平时编写Dao一样
public interface IUserDao {
public Long save(User user) throws Exception;
public User get(Long id) throws Exception;
public void delete(Long id) throws Exception;
public List<User> list() throws Exception;
}
编写测试类
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.List;
import org.dbunit.DatabaseTestCase;
import org.dbunit.database.IDatabaseConnection;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.xml.FlatXmlDataSet;
import org.dbunit.ext.h2.H2Connection;
import org.dbunit.ext.mysql.MySqlConnection;
import com.duowan.dbunitdemo.entity.User;
public class UserDaoTest extends DatabaseTestCase {
private IUserDao userDao;
@Override
protected void setUp() throws Exception {
userDao = new UserDaoImpl();
}
@Override
protected void tearDown() throws Exception {
userDao = null;
}
protected IDatabaseConnection getConnection() throws Exception {
Class.forName("org.h2.Driver");
Connection conn = DriverManager.getConnection("jdbc:h2:~/dbunitdemo", "sa", "");
return new H2Connection(conn, "dbunitdemo");
}
protected IDataSet getDataSet() throws Exception {
InputStream is = getClass().getResourceAsStream("/dbunitdemo-seed.xml");
System.out.println(is == null);
return new FlatXmlDataSet(is);
}
public void testGet() throws Exception{
User user = userDao.get(1L);
assertNotNull(user);
assertEquals("admin1", user.getUsername());
assertEquals("123", user.getPassword());
assertEquals("Administrator1", user.getName());
User nullUser = userDao.get(0L);
assertNull(nullUser);
}
public void testDelete() throws Exception{
User user = userDao.get(1L);
assertNotNull(user);
userDao.delete(1L);
User nullUser = userDao.get(1L);
assertNull(nullUser);
}
public void testList() throws Exception{
List<User> users = userDao.list();
assertNotNull(users);
assertEquals(4, users.size());
}
public void testSave() throws Exception{
User user = new User();
user.setName("testAdministrator");
user.setPassword("testPassword");
user.setUsername("testAdmin");
Long id = userDao.save(user);
assertNotNull(id);
User dbUser =userDao.get(id);
assertNotNull(dbUser);
assertEquals("testAdmin", dbUser.getUsername());
assertEquals("testPassword", dbUser.getPassword());
assertEquals("testAdministrator", dbUser.getName());
}
}
测试类说明:
//返回测试用的数据库连接对象
protected IDatabaseConnection getConnection() throws Exception { }
//返回测试用XML数据集对象
protected IDataSet getDataSet() throws Exception { }
jdbc连接方式格式为H2格式,H2会自动创建Database不用手工创建,但是表需要显式创建。这里是用用maven插件创建,工程以附件形上传。
基本原理就已经讲解完了,附件为例子程序,实现了一个领域模型类(User),一个Dao接口(IUserDao),定义了list\save \get\delete四个基本方法,一个用JDBC实现的Dao接口实现类(UserDaoImpl),建立一个UserDaoTest对JBDC版本 的Dao实现类进行测试。
另外这个工程使用maven进行build,如果对maven还是不很了解,请查考《Maven权威指南》
下载工程后,在项目根目录下执行mvn sql:execute,将使用Maven Sql插件导入src/main/sql/dbunitdemo.sql中的数据库脚本到数据库中。
然后可以直接运行mvn test进行单元测试,测试报告会在命令行输出,同时在target\surefire-reports下也会生成DBUnit报告。