`

Integrete unitils for database(dao) testing

 
阅读更多
引用
Database testing
Unit tests for the database layer can be extremely valuable when building enterprise applications, but are often abandoned because of their complexity. Unitils greatly reduces this complexity, making database testing easy and maintainable. The following sections describe the support that the DatabaseModule and DbUnitModule have to offer for your database tests.


引用
We extend XLS dataset for this sample

Build Tool:maven
DB: Hsql
Spring jdbc



1. maven dependency
<dependency>
			<groupId>org.unitils</groupId>
			<artifactId>unitils-io</artifactId>
			<version>3.3</version>
		</dependency>

		<dependency>
			<groupId>org.unitils</groupId>
			<artifactId>unitils-dbunit</artifactId>
			<version>3.3</version>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>org.unitils</groupId>
			<artifactId>unitils-spring</artifactId>
			<version>3.3</version>
			<scope>test</scope>
		</dependency>


		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi</artifactId>
			<version>3.2-FINAL</version>
			<type>jar</type>
			<scope>compile</scope>
		</dependency>


2. Create unitils.properties in classpath.
database.driverClassName=org.hsqldb.jdbcDriver
database.schemaNames=PUBLIC
database.url=jdbc:hsqldb:mem:poc
database.dialect=hsqldb
database.userName=sa
database.password=

DbUnitModule.DataSet.loadStrategy.default=org.unitils.dbunit.datasetloadstrategy.impl.CleanInsertLoadStrategy
DbUnitModule.DataSet.factory.default=com.wilson.unitils.MultiSchemaXlsDataSetFactory
DbUnitModule.ExpectedDataSet.factory.default=com.wilson.unitils.MultiSchemaXlsDataSetFactory




# The database maintainer is disabled by default.
updateDataBaseSchema.enabled=true
#This table is by default not created automatically
dbMaintainer.autoCreateExecutedScriptsTable=true
dbMaintainer.script.locations=src/test/resources/data

#dbMaintainer.script.fileExtensions=sql,ddl
#DbUnitModule.DataSet.loadStrategy.default=org.unitils.dbunit.datasetloadstrategy.impl.CleanInsertLoadStrategy
#DatabaseModule.Transactional.value.default=commit 

# XSD generator
dataSetStructureGenerator.xsd.dirName=resources/xsd


3. From the above configure, we can see MultiSchemaXlsDataSetReader and MultiSchemaXlsDataSetFactory are extended to support microsoft xls data set.
public class MultiSchemaXlsDataSetFactory implements DataSetFactory {

	protected String defaultSchemaName;

	public void init(Properties configuration, String defaultSchemaName) {
		this.defaultSchemaName = defaultSchemaName;
	}

	public MultiSchemaDataSet createDataSet(File... dataSetFiles) {
		try {
			MultiSchemaXlsDataSetReader xlsDataSetReader = new MultiSchemaXlsDataSetReader(
					defaultSchemaName);
			return xlsDataSetReader.readDataSetXls(dataSetFiles);
		} catch (Exception e) {
			throw new UnitilsException("创建数据集失败: "
					+ Arrays.toString(dataSetFiles), e);
		}
	}

	public String getDataSetFileExtension() {
		return "xls";
	}

}


public class MultiSchemaXlsDataSetReader {
	private String defaultSchemaName;
	
	public MultiSchemaXlsDataSetReader(String defaultSchemaName) {
		this.defaultSchemaName = defaultSchemaName;
	}	

	public MultiSchemaDataSet readDataSetXls(File... dataSetFiles) {
		try {
			Map<String, List<ITable>> tableMap = getTables(dataSetFiles);
			MultiSchemaDataSet dataSets = new MultiSchemaDataSet();
			for (Entry<String, List<ITable>> entry : tableMap.entrySet()) {
				List<ITable> tables = entry.getValue();
				try {
					DefaultDataSet ds = new DefaultDataSet(tables
							.toArray(new ITable[] {}));
					dataSets.setDataSetForSchema(entry.getKey(), ds);
				} catch (AmbiguousTableNameException e) {
					throw new UnitilsException("构造DataSet失败!",  e);
				}
			}
			return dataSets;
		} catch (Exception e) {
			throw new UnitilsException("解析EXCEL文件出错", e);
		}
	}

	private Map<String, List<ITable>> getTables(File... dataSetFiles) {
		Pattern pattern = Pattern.compile("\\.");
		Map<String, List<ITable>> tableMap = new HashMap<String, List<ITable>>();
		try {
			for (File file : dataSetFiles) {
				IDataSet dataSet = new XlsDataSet(new FileInputStream(file));
				String[] tableNames = dataSet.getTableNames();
				for (String each : tableNames) {
					String schema = null;
					String tableName;
					String[] temp = pattern.split(each);
					if (temp.length == 2) {
						schema = temp[0];
						tableName = temp[1];
					} else {
						schema = this.defaultSchemaName;
						tableName = each;
					}
					ITable table = dataSet.getTable(each);
					if (!tableMap.containsKey(schema)) {
						tableMap.put(schema, new ArrayList<ITable>());
					}
					tableMap.get(schema).add(new XlsTable(tableName, table));
				}
			}
		} catch (Exception e) {
			throw new UnitilsException("创建数据集失败: "
					+ Arrays.toString(dataSetFiles), e);
		}
		return tableMap;
	}

	class XlsTable extends AbstractTable {
		private ITable delegate;
		private String tableName;

		public XlsTable(String tableName, ITable table) {
			this.delegate = table;
			this.tableName = tableName;
		}

		public int getRowCount() {
			return delegate.getRowCount();
		}

		public ITableMetaData getTableMetaData() {
			ITableMetaData meta = delegate.getTableMetaData();
			try {
				return new DefaultTableMetaData(tableName, meta.getColumns(),
						meta.getPrimaryKeys());
			} catch (DataSetException e) {
				throw new UnitilsException("Don't get the meta info from  "
						+ meta, e);
			}
		}

		public Object getValue(int row, String column) throws DataSetException {
			Object delta = delegate.getValue(row, column);
			if (delta instanceof String) {
				if (StringUtils.isEmpty((String) delta)) {
					return null;
				}
			}
			return delta;
		}

	}
}


4. in the above confire, we can also see following configure, this mean when unitils starts, it use the ddl under dbMaintainer.script.locations to initial the hsql table structure
dbMaintainer.script.locations=src/test/resources/data


We just create one table for testing
CREATE TABLE T_USER (USER_ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 1) NOT NULL PRIMARY KEY, USER_NAME VARCHAR(40) NOT NULL, PASSWORD VARCHAR(40) NOT NULL);


5. Our Unit test sample
package com.wilson.unitils;

import org.junit.Assert;
import org.junit.Test;
import org.unitils.UnitilsJUnit4;
import org.unitils.dbunit.annotation.DataSet;
import org.unitils.spring.annotation.SpringApplicationContext;
import org.unitils.spring.annotation.SpringBean;

import com.wilson.dbunit.User;
import com.wilson.dbunit.UserDao;

@SpringApplicationContext("com/wilson/unitils/applicationContext.xml")
public class UserDaoUnitilsTest extends UnitilsJUnit4{
	@SpringBean("userDao")
	protected UserDao userDao;
	
	@Test
	@DataSet("UserDaoUnitilsTest_findUser.xls")
	public void findUser() throws Exception {
		User user = userDao.findUserByUserName("admin");
		System.out.println(user);
		Assert.assertEquals("123456", user.getPassword());
	}
}


From the above code, we use import the data in UserDaoUnitilsTest_findUser.xls to hsql database, sheet name is table name, the first line is the column names


Database DDL:
CREATE TABLE T_USER (USER_ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 1) NOT NULL PRIMARY KEY, USER_NAME VARCHAR(40) NOT NULL, PASSWORD VARCHAR(40) NOT NULL);


another test case for validate db insert result. we need add annotion @ExpectedDataSet
	@Test
	@ExpectedDataSet("UserDaoUnitilsTest_registerUser.xls")
	public void testRegisterUser() throws Exception {
		User user = new User();
		user.setUserId(3);
		user.setUserName("user001");
		user.setPassword("123456");
		userDao.RegisterUser(user);
	}



The t_user table should has same content as the UserDaoUnitilsTest_registerUser.xls


6. if we want spring use the same datasource with unitils, we can add following as datasource in spring configure file.[repository\src\test\java\com\wilson\unitils\applicationContext.xml]
<bean id="dataSource" class="org.unitils.database.UnitilsDataSourceFactoryBean" />


Other code is related to spring jdbc and it's really simple , you can refer to the attachment. Be sure you have maven installed before running.

  • 大小: 23.1 KB
  • 大小: 5.8 KB
分享到:
评论

相关推荐

    MySQL for Database Administrators Student Guide - Volume I

    由于提供的文件内容非常有限,并且主要是由随机字母组成的,无法提供一个连贯的文档内容理解。但是,根据文件标题、描述和标签,可以推测出文档是关于MySQL数据库管理员专业认证的教材。以下将基于此背景提供与MySQL...

    Oracle Database 12c Release 2 Testing Tools and Techniques for Performance azw3

    Oracle Database 12c Release 2 Testing Tools and Techniques for Performance and Scalability 英文azw3 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系上传者或...

    数据库连接测试_&_遗传算法预测股价买卖_Database-Testing-and-Stock-Forecasting.zip

    数据库连接测试_&_遗传算法预测股价买卖_Database-Testing-and-Stock-Forecasting

    Unitils单元测试

    Unitils的模块化设计是其另一大特点,包括unitils-core(核心模块)、unitils-database(数据库管理)、unitils-DbUnit(DbUnit集成)、unitils-easymock(EasyMock支持)、unitils-inject(对象注入)、unitils-...

    Oracle Database Real Application Testing User’s Guide 11g Releas

    Oracle Database Real Application Testing User’s Guide 11g Release 2 (11.2) 是一份详细的技术文档,旨在帮助数据库管理员和IT专业人员利用Oracle数据库的实时应用测试功能进行高效且可靠的性能优化和故障预防。...

    paper: Generalized Search Trees for Database Systems

    In a single data structure, the GiST provides all the basic search tree logic required by a database system, thereby unifying disparate structures such as B+-trees and R-trees in a single piece of ...

    Unitils教程(介绍Unitils的最佳资料)

    例如,我们可以使用 Unitils 的 DatabaseModule 来测试数据库操作。DatabaseModule 提供了一些实用的方法来操作数据库,例如创建、删除和更新数据库记录。 应用 Spring 测试 ---------------- 在单元测试中,我们...

    Java数据库dao层框架(DataBase1.0)

    Java数据库DAO层框架Database1.0是一个旨在简化数据库操作的工具,主要针对JDBC的连接管理进行了封装,以提高开发效率。DAO(Data Access Object)层是软件设计中用于访问数据库的一层抽象,它隔离了应用程序与数据...

    Pro PowerShell for Database Developers(Apress,2015)

    Pro PowerShell for Database Developers helps you master PowerShell application development by continuing where other books leave off. There are no "Hello World" functions here, just real-world ...

    - UML for Database Design

    - UML for Database Design

    SQLite Database Browser for mac os

    SQLite Database Browser 是一款专为Mac OS设计的直观易用的数据库管理工具,它专注于处理SQLite数据库文件。SQLite是一种轻量级、自包含的数据库引擎,广泛应用于移动设备、嵌入式系统以及桌面应用中,因为它不需要...

    用DAO建立Access数据库文件

    在DAO中,Database对象代表整个数据库,TableDef对象表示数据库中的表格定义,Recordset对象则用于处理表格中的记录。 要使用DAO创建Access数据库文件,首先需要引入DAO库。在Visual Basic中,可以通过以下代码引入...

    Unitils框架与模块扩展

    Unitils框架与模块扩展Unitils这个Java开源包的目的是让单元测试变得更加容易和维护。Unitils构建在DBUnit与EasyMock项目之上并与JUnit和TestNG相结合,支持数据库测试,支持利用mock对象进行测试并提供与Spring和...

    DAO.Database.Collection.v3.9.For.Delphi567.BCB456.Cracked

    Delphi and C++ Builder components for accessing MS Access databases using DAO 3.5 and 3.6 (Data Access Objects). Provides fast native access to data without need of BDE (Borland Database Engine).

    数据库系统概念答案 Solution for Database System Concepts(Fifth edition)

    数据库系统概念答案,英文版,原书Abraham Silberschatz, Henry F.Korth, S.Sudarshan编著版本

    Dao Jet数据库引擎

    DAO接口提供了多种类和接口,如Database、Recordset、Field等,开发者可以通过这些对象来执行SQL查询、创建和修改表、索引和查询。DAO与ADO(ActiveX Data Objects)相比,虽然功能上稍微弱一些,但因为其更接近底层...

    Absolute Database for D7

    Overview Absolute Database: Delphi database with SQL support.Absolute Database lets you forget the Borland Database Engine (BDE). This BDE replacement is the compact, high-speed, robust and easy-to-...

Global site tag (gtag.js) - Google Analytics