Unitils集成DBUnit、Spring-单元测试

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介:

 Unitils集成DBUnit、Spring-单元测试

  1、maven-pom文件中引入相关jar包  

复制代码
<!-- Unitils -dbunit、Spring -->
        <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>
复制代码

  以上Unitils集成dbunit、Spring所必须jar包,工程文件是通过maven构建的,所以都是maven的目录结构。

  2、引入unitils的配置文件unitils.properties,这个配置文件可以用unitils-core的jar包中copy出来,然后进行自定义配置,如下:

复制代码
#启用unitils所需模块
unitils.modules=database,dbunit,spring

#自定义扩展模块,详见实例源码
#unitils.module.dbunit.className=org.unitils.dbunit.DbUnitModule
unitils.module.dbunit.className=com.candle.util.MySqlDbUnitModule

#配置数据库连接
database.driverClassName=com.mysql.jdbc.Driver
database.url=jdbc:mysql://127.0.0.1:3306/test?autoReconnect=true&amp;useUnicode=true&amp;characterEncoding=utf-8
database.userName=root
database.password=123qwe
#配置为数据库名称
database.schemaNames=test
#配置数据库方言
database.dialect=mysql

#配置数据库维护策略.请注意下面这段描述
# 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=false #配置数据库表创建策略,是否自动建表以及建表sql脚本存放目录 #dbMaintainer.autoCreateExecutedScriptsTable=false #dbMaintainer.script.locations=D:\workspace\unit-demo\src\test\java\com\candle\dao #数据集加载策略 #CleanInsertLoadStrategy:先删除dateSet中有关表的数据,然后再插入数据 #InsertLoadStrategy:只插入数据 #RefreshLoadStrategy:有同样key的数据更新,没有的插入 #UpdateLoadStrategy:有同样key的数据更新,没有的不做任何操作 DbUnitModule.DataSet.loadStrategy.default=org.unitils.dbunit.datasetloadstrategy.impl.CleanInsertLoadStrategy #配置数据集工厂 DbUnitModule.DataSet.factory.default=org.unitils.dbunit.datasetfactory.impl.MultiSchemaXmlDataSetFactory DbUnitModule.ExpectedDataSet.factory.default=org.unitils.dbunit.datasetfactory.impl.MultiSchemaXmlDataSetFactory #配置事务策略 commit、rollback 和disabled;或者在代码的方法上标记@Transactional(value=TransactionMode.ROLLBACK) #commit 是单元测试方法过后提交事务 #rollback 是回滚事务 #disabled 是没有事务,默认情况下,事务管理是disabled DatabaseModule.Transactional.value.default=disabled #配置数据集结构模式XSD生成路径,可以自定义目录,但不能为空 dataSetStructureGenerator.xsd.dirName=/ dbMaintainer.generateDataSetStructure.enabled=true
复制代码

  自定义配置文件有两个,分别是unitils.properties和unitils-local.properties,但通常我们只需要配置unitils.properties即可,这个配置文件默认是放在工程的根目录下,我这里的测试

根目录是/src/test/resources/下。因为unitils默认是这样去读取配置文件的,所以不建议移动到其他目目录,不然可能需要更改读取配置文件的代码了。

  3、写一个mysql数据库配置的类,用于解决dbunit中存在的bug,在上一篇博客中有讲到,代码如下  

复制代码
package com.candle.util;

import org.dbunit.database.DatabaseConfig;
import org.dbunit.ext.mysql.MySqlDataTypeFactory;
import org.dbunit.ext.mysql.MySqlMetadataHandler;
import org.unitils.dbunit.DbUnitModule;
import org.unitils.dbunit.util.DbUnitDatabaseConnection;

public class MySqlDbUnitModule extends DbUnitModule {

    @Override
    public DbUnitDatabaseConnection getDbUnitDatabaseConnection(
            final String schemaName) {
        DbUnitDatabaseConnection result = dbUnitDatabaseConnections
                .get(schemaName);
        if (null != result) {
            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;
    }
}
复制代码

  加如上类之后,再去看unitils.properties中  

#自定义扩展模块,详见实例源码
#unitils.module.dbunit.className=org.unitils.dbunit.DbUnitModule
unitils.module.dbunit.className=com.candle.util.MySqlDbUnitModule          
如上就制定到自定义的类
com.candle.util.MySqlDbUnitModule,解决dbunit中可能存在的bug

4、准备测试数据
@DataSet和@ExpectedDataSet
这里都用xml来存放数据,如果要用excel,需要重写excel获取数据的相关代码
xml存放路径如下:src/test/resources/dataSetXml/,目录下包括@DataSet数据(login.xml)和@ExpectedDataSet数据login_expect.xml

5、测试代码
复制代码
package com.candle.dao;

import static org.junit.Assert.*;

import org.junit.Test;
import org.unitils.UnitilsJUnit4;
import org.unitils.database.annotations.Transactional;
import org.unitils.database.util.TransactionMode;
import org.unitils.dbunit.annotation.DataSet;
import org.unitils.dbunit.annotation.ExpectedDataSet;
import org.unitils.reflectionassert.ReflectionAssert;
import org.unitils.spring.annotation.SpringApplicationContext;
import org.unitils.spring.annotation.SpringBean;

import com.candle.model.LoginDO;

@SpringApplicationContext({"applicationContext-test.xml"})
public class LoginDAOTest5 extends UnitilsJUnit4{
    
    //Spring容器中加载Id为"userService"的Bean
    @SpringBean("loginDAO")
    private LoginDAO loginDAO ;

    
    @Test
    @ExpectedDataSet("/dataSetXml/login_expect.xml")
    public void testSaveLogin() {
        LoginDO loginDo = new LoginDO();
        loginDo.setId(2);
        loginDo.setName("thomas");
        loginDo.setPasswd("123qwe");
        loginDAO.saveLogin(loginDo);
    }

    
    @Test
    @DataSet("/dataSetXml/login.xml")
    //@Transactional(value=TransactionMode.ROLLBACK)
    public void testFindById() {
        LoginDO loginDo = loginDAO.findById(1) ;
        ReflectionAssert.assertPropertyLenientEquals("name","candle",loginDo) ;
        assertNotNull("空置", loginDo);
        assertEquals("candle",loginDo.getName()) ;
    }
    
}
复制代码

  其中,关于unitils集成spring,就是通过集成UnitilsJUnit4类引入spring的配置文件,即可完成Spring的bean之类的重用~

  6、回滚问题

  通过以上配置,包括事务配置,通过测试发现,unitils的事务是集成自Spring的,所以如果当测试类中集成了Spring的applicationContext配置文件,则unitils中的事务配置无效,这里测试过回滚事务,

  DatabaseModule.Transactional.value.default=rollback,在测试中引用Spring的配置时,此回滚无效,如果不引用Spring的配置,则可以生效~

  此问题有待研究~

  






本文转自一米一阳光博客园博客,原文链接:  http://www.cnblogs.com/candle806/p/3810061.html  ,如需转载请自行联系原作者


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1月前
|
Java 测试技术 开发者
必学!Spring Boot 单元测试、Mock 与 TestContainer 的高效使用技巧
【10月更文挑战第18天】 在现代软件开发中,单元测试是保证代码质量的重要手段。Spring Boot提供了强大的测试支持,使得编写和运行测试变得更加简单和高效。本文将深入探讨Spring Boot的单元测试、Mock技术以及TestContainer的高效使用技巧,帮助开发者提升测试效率和代码质量。
172 2
|
3月前
|
Java 测试技术 开发者
在软件开发中,测试至关重要,尤以单元测试和集成测试为然
在软件开发中,测试至关重要,尤以单元测试和集成测试为然。单元测试聚焦于Java中的类或方法等最小单元,确保其独立功能正确无误,及早发现问题。集成测试则着眼于模块间的交互,验证整体协作效能。为实现高效测试,需编写可测性强的代码,并选用JUnit等合适框架。同时,合理规划测试场景与利用Spring等工具也必不可少。遵循最佳实践,可提升测试质量,保障Java应用稳健前行。
51 1
|
3月前
|
XML Java 测试技术
Spring5入门到实战------17、Spring5新功能 --Nullable注解和函数式注册对象。整合JUnit5单元测试框架
这篇文章介绍了Spring5框架的三个新特性:支持@Nullable注解以明确方法返回、参数和属性值可以为空;引入函数式风格的GenericApplicationContext进行对象注册和管理;以及如何整合JUnit5进行单元测试,同时讨论了JUnit4与JUnit5的整合方法,并提出了关于配置文件加载的疑问。
Spring5入门到实战------17、Spring5新功能 --Nullable注解和函数式注册对象。整合JUnit5单元测试框架
|
28天前
|
Kubernetes 测试技术 持续交付
C# 一分钟浅谈:集成测试与系统测试
【10月更文挑战第19天】本文详细介绍了集成测试和系统测试的概念、目的及其在软件开发中的重要性。通过分析常见问题和易错点,结合代码示例,探讨了如何通过代码规范、自动化测试和持续集成等方法提高测试效果,确保软件质量和可靠性。
52 1
|
1月前
|
存储 人工智能 Java
将 Spring AI 与 LLM 结合使用以生成 Java 测试
AIDocumentLibraryChat 项目通过 GitHub URL 为指定的 Java 类生成测试代码,支持 granite-code 和 deepseek-coder-v2 模型。项目包括控制器、服务和配置,能处理源代码解析、依赖加载及测试代码生成,旨在评估 LLM 对开发测试的支持能力。
38 1
|
2月前
|
Devops jenkins 测试技术
DevOps实践:持续集成与自动化测试的融合之道
【9月更文挑战第29天】在软件开发的快节奏竞赛中,DevOps如同一位智慧的舵手,引领着船只驶向效率与质量的彼岸。本文将揭开DevOps的神秘面纱,探索其核心理念如何通过持续集成(CI)和自动化测试的实践,实现软件开发流程的优化与加速。我们将一同见证代码从构思到部署的旅程,以及这一过程中的关键技术和工具如何协同工作,确保软件质量和交付速度的双重提升。
|
2月前
|
JavaScript 前端开发 Java
Spring Boot+cucumber+契约测试
Spring Boot+cucumber+契约测试
22 0
Spring Boot+cucumber+契约测试
|
3月前
|
jenkins 测试技术 持续交付
解锁.NET项目高效秘籍:从理论迷雾到实践巅峰,持续集成与自动化测试如何悄然改变游戏规则?
【8月更文挑战第28天】在软件开发领域,持续集成(CI)与自动化测试已成为提升效率和质量的关键工具。尤其在.NET项目中,二者的结合能显著提高开发速度并保证软件稳定性。本文将从理论到实践,详细介绍CI与自动化测试的重要性,并以ASP.NET Core Web API项目为例,演示如何使用Jenkins和NUnit实现自动化构建与测试。每次代码提交后,Jenkins自动触发构建流程,通过编译和运行NUnit测试确保代码质量。这种方式不仅节省了时间,还能快速发现并解决问题,推动.NET项目开发迈向更高水平。
51 8
|
3月前
|
测试技术 Java Spring
Spring 框架中的测试之道:揭秘单元测试与集成测试的双重保障,你的应用真的安全了吗?
【8月更文挑战第31天】本文以问答形式深入探讨了Spring框架中的测试策略,包括单元测试与集成测试的有效编写方法,及其对提升代码质量和可靠性的重要性。通过具体示例,展示了如何使用`@MockBean`、`@SpringBootTest`等注解来进行服务和控制器的测试,同时介绍了Spring Boot提供的测试工具,如`@DataJpaTest`,以简化数据库测试流程。合理运用这些测试策略和工具,将助力开发者构建更为稳健的软件系统。
60 0
|
3月前
|
Java Spring UED
Spring框架的异常处理秘籍:打造不败之身的应用!
【8月更文挑战第31天】在软件开发中,异常处理对应用的稳定性和健壮性至关重要。Spring框架提供了一套完善的异常处理机制,包括使用`@ExceptionHandler`注解和配置`@ControllerAdvice`。本文将详细介绍这两种方式,并通过示例代码展示其具体应用。`@ExceptionHandler`可用于控制器类中的方法,处理特定异常;而`@ControllerAdvice`则允许定义全局异常处理器,捕获多个控制器中的异常。
52 0
下一篇
无影云桌面