`

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
分享到:
评论

相关推荐

    pimpinella_3cd_01_0716.pdf

    pimpinella_3cd_01_0716

    FIB English learning

    FIB English learning

    linux下 jq 截取json文件信息

    X86-jq安装包

    [AB PLC例程源码][MMS_046356]SELX.zip

    AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!

    大圣挪车小程序1.3.5+前端.zip

    大圣挪车小程序1.3.5 前端

    Manus.im 产品及开发团队研究报告.pdf

    Manus.im 产品及开发团队研究报告.pdf

    [AB PLC例程源码][MMS_044663]Control daisy chain wiring in Fieldbus Foundation.zip

    AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!

    sun_3ck_01a_0918.pdf

    sun_3ck_01a_0918

    支持适用于PERC H330/H730/H730P/H830/H730P系列RAID卡MX/FD33xD/FD33xS控制器的驱动安装指南

    下载 1. 单击“立即下载”,以下载该文件。 2. 出现“文件下载”窗口后,单击“保存”,以将文件保存到硬盘。 安装 1. 浏览至文件下载目标位置并双击新下载的文件。 2. 仔细阅读对话窗口中显示的发布信息。 3. 下载并安装对话窗口中标识的任何必备项,然后再继续。 4. 单击“Install”(安装)按钮。 5. 按照其余提示执行更新。 安装 1. 将解压的文件复制到可访问Windows的介质。 2. 将系统重新引导至Windows操作系统。 3. 打开“服务器管理器”->“设备管理器”->“存储控制器”,然后单击“PERC控制器”。 5. 单击“更新驱动程序软件”,并按照提示更新驱动程序。 4. 重新引导系统以使更改生效。

    硬盘安装器,支持硬盘安装,无需制作U盘PE!

    支持所有操作系统一键安装。

    matlab程序代码项目案例:使用 Simulink 进行自适应 MPC 设计

    matlab程序代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!

    [AB PLC例程源码][MMS_044098]1769-ASCII Simultaneous Mode.zip

    AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!

    swanson_01_1106.pdf

    swanson_01_1106

    [AB PLC例程源码][MMS_047811]SAF1 - Store.zip

    AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!

    [AB PLC例程源码][MMS_043879]Programming in SFC and ST Language.zip

    AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!

    sun_3ck_01_0919.pdf

    sun_3ck_01_0919

    方言距离数据.岭南学院产业与区域经济研究中心

    各城市方言距离数据-中山大学岭南学院产业与区域经济研究中心 方言距离是指两种或多种方言之间的相似程度或差异程度。参考中山大学岭南学院产业与区域经济研究中心的刘毓芸等(2015)文献。他们基于方言树图,并参考《汉语方言大词典》和《中国语言地图集》对方言的划分,将汉语方言从宽泛到具体分为以下几个层级:汉语→方言大区→方言区→方言片。为了量化县与县之间的方言差异,他们采用了一种赋值方法: 若它们分属不同方言大区,则距离为3。: 若两个县同属一个方言片,则它们之间的方言距离为0; 若两个县属于同一方言区但不同方言片,则距离为1; 若它们属于同一方言大区但不同方言区,则距离为2; 方言距离是一个反映方言之间相似程度或差异程度的重要指标,它在语音识别、方言研究等领域具有广泛的应用价值。 参考文献:[1]刘毓芸, 徐现祥, 肖泽凯. 2015. 劳动力跨方言流动的倒U型模式[J]. 经济研究, 50(10): 134-146+162. 指标 语系、语族、方言大区、方言区/语支、方言片/语种、Supergroup、Dialect、group、Sub-dialect、groupPref_1、Pref_2、DiaDist、PrefCode_1、PrefCode_2等等。

    基于PCA算法的人脸识别MATLAB源码

    基于PCA算法的人脸识别MATLAB源码

    [AB PLC例程源码][MMS_045740]Handling manual movement of axis using an Add On Instruction (AOI), .zip

    AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!

Global site tag (gtag.js) - Google Analytics