第一步:pom依赖
<!-- 单元测试 --> <dependency> <groupId>org.unitils</groupId> <artifactId>unitils-core</artifactId> <version>3.4.2</version> </dependency> <dependency> <groupId>org.unitils</groupId> <artifactId>unitils-dbunit</artifactId> <version>3.4.2</version> </dependency> <dependency> <groupId>org.unitils</groupId> <artifactId>unitils-io</artifactId> <version>3.4.2</version> </dependency> <dependency> <groupId>org.unitils</groupId> <artifactId>unitils-database</artifactId> <version>3.4.2</version> </dependency> <dependency> <groupId>org.unitils</groupId> <artifactId>unitils-spring</artifactId> <version>3.4.2</version> </dependency> <dependency> <groupId>org.dbunit</groupId> <artifactId>dbunit</artifactId> <version>2.5.3</version> </dependency> <dependency> <groupId>org.easymock</groupId> <artifactId>easymock</artifactId> <version>3.5.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.easymock</groupId> <artifactId>easymock</artifactId> <version>RELEASE</version> </dependency> <dependency> <groupId>org.unitils</groupId> <artifactId>unitils-core</artifactId> <version>3.4.2</version> </dependency> <dependency> <groupId>org.unitils</groupId> <artifactId>unitils-dbunit</artifactId> <version>3.4.2</version> </dependency> <dependency> <groupId>org.unitils</groupId> <artifactId>unitils-io</artifactId> <version>3.4.2</version> </dependency> <dependency> <groupId>org.unitils</groupId> <artifactId>unitils-database</artifactId> <version>3.4.2</version> </dependency> <dependency> <groupId>org.unitils</groupId> <artifactId>unitils-spring</artifactId> <version>3.4.2</version> </dependency> <dependency> <groupId>org.dbunit</groupId> <artifactId>dbunit</artifactId> <version>2.5.3</version> </dependency>
pom
第二步:编写关于unitils的4个工具类,我现在放在unitils包下
package com.odianyun.back.order.web.unitils; import java.io.File; import java.util.Arrays; import java.util.Properties; import org.unitils.core.UnitilsException; import org.unitils.dbunit.datasetfactory.DataSetFactory; import org.unitils.dbunit.util.MultiSchemaDataSet; public class MultiSchemaXlsDataSetFactory implements DataSetFactory { protected String defaultSchemaName; public void init(Properties configuration, String s) { this.defaultSchemaName = s; } 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"; } }
MultiSchemaXlsDataSetFactory
package com.odianyun.unitils; import org.dbunit.database.AmbiguousTableNameException; import org.dbunit.dataset.DefaultDataSet; import org.dbunit.dataset.IDataSet; import org.dbunit.dataset.ITable; import org.dbunit.dataset.excel.XlsDataSet; import org.unitils.core.UnitilsException; import org.unitils.dbunit.util.MultiSchemaDataSet; import java.io.File; import java.io.FileInputStream; import java.util.*; public class MultiSchemaXlsDataSetReader { private String pattern = "."; private String defaultSchemaName; public MultiSchemaXlsDataSetReader(String defaultSchemaName) { this.defaultSchemaName = defaultSchemaName; } public MultiSchemaDataSet readDataSetXls(File... dataSetFiles) { try { Map<String, List<ITable>> tbMap = getTables(dataSetFiles); MultiSchemaDataSet dataSets = new MultiSchemaDataSet(); for (Map.Entry<String, List<ITable>> entry : tbMap.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) { Map<String, List<ITable>> tableMap = new HashMap(); // 需要根据schema把Table重新组合一下 try { String schema, tableName; for (File file : dataSetFiles) { IDataSet dataSet = new XlsDataSet(new FileInputStream(file)); String[] tableNames = dataSet.getTableNames(); for (String tn : tableNames) { String[] temp = tn.split(pattern); if (temp.length == 2) { schema = temp[0]; tableName = temp[1]; } else { schema = this.defaultSchemaName; tableName = tn; } ITable table = dataSet.getTable(tn); if (!tableMap.containsKey(schema)) { tableMap.put(schema, new ArrayList<ITable>()); } tableMap.get(schema).add(new XslTableWrapper(tableName, table)); } } } catch (Exception e) { throw new UnitilsException("Unable to create DbUnit dataset for data set files: " + Arrays.toString(dataSetFiles), e); } return tableMap; } }
MultiSchemaXlsDataSetReader
package com.odianyun.unitils; import org.dbunit.database.DatabaseConfig; import org.dbunit.ext.mysql.MySqlDataTypeFactory; import org.dbunit.ext.mysql.MySqlMetadataHandler; import org.unitils.core.UnitilsException; import org.unitils.dbmaintainer.locator.ClassPathDataLocator; import org.unitils.dbmaintainer.locator.resourcepickingstrategie.ResourcePickingStrategie; import org.unitils.dbunit.DbUnitModule; import org.unitils.dbunit.datasetfactory.DataSetFactory; import org.unitils.dbunit.util.DbUnitDatabaseConnection; import org.unitils.dbunit.util.MultiSchemaDataSet; import java.io.File; import java.io.InputStream; import java.util.ArrayList; import java.util.List; public class MyDbUnitModule extends DbUnitModule { //完善DbUnitDatabaseConnection连接信息 @Override public DbUnitDatabaseConnection getDbUnitDatabaseConnection(final String schemaName) { DbUnitDatabaseConnection result = dbUnitDatabaseConnections.get(schemaName); if (result != null) { return result; } result = super.getDbUnitDatabaseConnection(schemaName); result.getConfig().setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new MySqlDataTypeFactory()); result.getConfig().setProperty(DatabaseConfig.PROPERTY_METADATA_HANDLER, new MySqlMetadataHandler()); return result; } //Excel预处理操作,将@DataSet注释读取的文件返回给DataSetFactory进行处理 @Override protected File handleDataSetResource(ClassPathDataLocator locator, String nameResource, ResourcePickingStrategie strategy, Class<?> testClass) { String cloneResource = new String(nameResource); String packageName = testClass.getPackage() != null?testClass.getPackage().getName():""; String tempName = ""; if(cloneResource.startsWith(packageName.replace(".", "/"))) { cloneResource = tempName = cloneResource.substring(packageName.length()); } else if(cloneResource.startsWith(packageName)) { cloneResource = tempName = cloneResource.substring(packageName.length() + 1); } else { tempName = cloneResource; } InputStream in = locator.getDataResource(packageName.replace(".", "/") + "/" + tempName, strategy); File resolvedFile = null; if(in == null) { resolvedFile = this.getDataSetResolver().resolve(testClass, cloneResource); if(resolvedFile == null) { throw new UnitilsException("DataSetResource file with name ‘" + nameResource + "‘ cannot be found"); } } return resolvedFile; } //调用DataSetFactory.createDataSet()向数据库中注入Excel数据后,直接返回DataSet,不对DataSet执行清零操作 @Override protected MultiSchemaDataSet getDataSet(Class<?> testClass, String[] dataSetFileNames, DataSetFactory dataSetFactory) { List<File> dataSetFiles = new ArrayList<File>(); ResourcePickingStrategie resourcePickingStrategie = getResourcePickingStrategie(); for (String dataSetFileName : dataSetFileNames) { File dataSetFile = handleDataSetResource(new ClassPathDataLocator(), dataSetFileName, resourcePickingStrategie, testClass); dataSetFiles.add(dataSetFile); } MultiSchemaDataSet dataSet = dataSetFactory.createDataSet(dataSetFiles.toArray(new File[dataSetFiles.size()])); return dataSet; } }
MyDbUnitModule
package com.odianyun.unitils; import org.apache.commons.lang.StringUtils; import org.dbunit.dataset.*; import org.unitils.core.UnitilsException; class XslTableWrapper extends AbstractTable { private ITable delegate; private String tableName; public XslTableWrapper(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; } }
XslTableWrapper
第三步:在test下创建一个dbscripts的sql的ddl文件
我就随便到处了数据结构的
SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for sys_role -- ---------------------------- DROP TABLE IF EXISTS `sys_role`; CREATE TABLE `sys_role` ( `id` int(10) NOT NULL AUTO_INCREMENT, `name` varchar(50) COLLATE utf8_bin DEFAULT NULL, `status` int(2) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
init.sql
第四步:配置
unitils.modules=database,dbunit,spring #自定义扩展模块,加载Excel文件,默认拓展模块org.unitils.dbunit.DbUnitModule支持xml #unitils.module.dbunit.className=org.unitils.dbunit.DbUnitModule unitils.module.dbunit.className=com.odianyun.unitils.MyDbUnitModule #配置数据库连接 database.driverClassName=com.mysql.jdbc.Driver database.url=jdbc:mysql://127.0.0.1:3306/dbtest?autoReconnect=true&useUnicode=true&characterEncoding=utf-8 database.userName=root database.password=root #配置为数据库名称 database.schemaNames=dbtest #配置数据库方言 database.dialect=mysql #需设置false,否则我们的测试函数只有在执行完函数体后,才将数据插入的数据表中 unitils.module.database.runAfter=false #配置数据库维护策略.请注意下面这段描述 # If set to true, the DBMaintainer will be used to update the unit test database schema. This is done once for each # test run, when creating the DataSource that provides access to the unit test database. updateDataBaseSchema.enabled=true #配置数据库表创建策略,是否自动建表以及建表sql脚本存放目录 dbMaintainer.autoCreateExecutedScriptsTable=true dbMaintainer.keepRetryingAfterError.enabled=true dbMaintainer.script.locations=src/test/resources/dbscripts #dbMaintainer.script.fileExtensions=sql #数据集加载策略 #CleanInsertLoadStrategy:先删除dateSet中有关表的数据,然后再插入数据 #InsertLoadStrategy:只插入数据 #RefreshLoadStrategy:有同样key的数据更新,没有的插入 #UpdateLoadStrategy:有同样key的数据更新,没有的不做任何操作 DbUnitModule.DataSet.loadStrategy.default=org.unitils.dbunit.datasetloadstrategy.impl.CleanInsertLoadStrategy #配置数据集工厂,自定义 DbUnitModule.DataSet.factory.default=com.odianyun.unitils.MultiSchemaXlsDataSetFactory DbUnitModule.ExpectedDataSet.factory.default=com.odianyun.unitils.MultiSchemaXlsDataSetFactory #配置事务策略 commit、rollback 和disabled;或者在代码的方法上标记@Transactional(value=TransactionMode.ROLLBACK) #commit 是单元测试方法过后提交事务 #rollback 是回滚事务 #disabled 是没有事务,默认情况下,事务管理是disabled DatabaseModule.Transactional.value.default=commit #配置数据集结构模式XSD生成路径,可以自定义目录,但不能为空 dataSetStructureGenerator.xsd.dirName=src/test/resources/xsd dbMaintainer.generateDataSetStructure.enabled=true #文件相对路径是否是测试类文件路径,false表示resource根目录 dbUnit.datasetresolver.prefixWithPackageName=false
unitils.properties
第五步:创建BaseUnitsTest类
package com.test; import org.junit.BeforeClass; import org.junit.runner.RunWith; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.unitils.UnitilsJUnit4TestClassRunner; /** * @author 危常焕 * @time 2017/11/28 * @description https://github.com/newsoulbr/mokitopoc/blob/master/src/test/java/com/github/newsoulbr/mokitopoc/service/PersonServiceTest.java * http://www.unitils.org/tutorial-reflectionassert.html * http://blog.csdn.net/achuo/article/details/47726241 * */ @RunWith(UnitilsJUnit4TestClassRunner.class) public class BaseUnitilsTest { protected static ApplicationContext ctx; protected static ConfigurableApplicationContext configurableContext; protected static BeanDefinitionRegistry beanDefinitionRegistry; @BeforeClass public static void setUpBeforeClass() { ctx = new ClassPathXmlApplicationContext("classpath*:applicationContext.xml"); configurableContext = (ConfigurableApplicationContext) ctx; beanDefinitionRegistry = (DefaultListableBeanFactory) configurableContext.getBeanFactory(); } public static void registerBean(String beanId, String className) { // get the BeanDefinitionBuilder BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(className); // get the BeanDefinition BeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition(); // register the bean beanDefinitionRegistry.registerBeanDefinition(beanId, beanDefinition); } /** * 移除bean * * @param beanId * bean的id */ public static void unregisterBean(String beanId) { beanDefinitionRegistry.removeBeanDefinition(beanId); } }
BaseUnitilsTest
第六步:准备excel:sheet是代表表名:第一列是列名:一行是一个对象
第七步:测试
package com.test; import com.po.SysRoleResource; import com.service.SysRoleResourceService; import com.service.impl.SysRoleResourceServiceImpl; import org.junit.Before; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.unitils.dbunit.annotation.DataSet; public class TestDemo2 extends BaseUnitilsTest { private Logger logger = LoggerFactory.getLogger(this.getClass()); private SysRoleResourceService sysRoleResourceService; @Before public void setUp() { sysRoleResourceService = (SysRoleResourceService) ctx.getBean(SysRoleResourceServiceImpl.class); } @Test @DataSet(value = { "excel\\demo.xls" }) // 通过Unitils提供的@DataSet注解从当前测试类this.class所在的目录寻找支持DbUnit的数据集文件并进行加载。 // 执行测试逻辑之前,会把加载的数据集先持久化到测试数据库中, // @ExpectedDataSet(value = { // "com\\odianyun\\demo\\dao\\WarehouseDAOTestdemo.xls" }) // 是在单元测试之后进行数据比对 // 从当前测试类this.class所在的目录寻找支持DbUnit的验证数据集文件并进行加载, // 之后验证数据集里的数据和数据库中的数据是否一致 public void selectByPrimaryKey() { SysRoleResource selectByPrimaryKey = sysRoleResourceService.selectByPrimaryKey(1); System.err.println(selectByPrimaryKey.getRoleId()); logger.debug(selectByPrimaryKey.getRoleId() + ""); }; }
test类
时间: 2025-01-18 02:22:38