zoukankan      html  css  js  c++  java
  • 关于单元测试之王

    第一步: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&amp;useUnicode=true&amp;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类
  • 相关阅读:
    POCO库——Foundation组件之日期时间DateTime
    POCO库——Foundation组件之加解密Crypt
    POCO库——Foundation组件之缓存Cache
    POCO库——Foundation组件之核心Core
    POCO库——Foundation组件概述
    HP-SOCKET TCP/UDP通信框架库解析
    Notepad++ 使用nppexec插件配置简易开发环境
    Duilib源码分析(五)UI布局—Layout与各子控件
    Breakpad Google的crash捕获、抓取开源库
    Pugixml一种快速解析XML文件的开源解析库
  • 原文地址:https://www.cnblogs.com/wchxj/p/8048211.html
Copyright © 2011-2022 走看看