SpringBoot中如何对数据访问层进行单元测试?

2023年 7月 19日 68.2k 0

前言

我们公司作为一个面向银行、金融机构的TO B类企业,频繁遇到各个甲方爸爸提出的国产化数据库的改造需求,包括OceanBase, TiDBgeldenDB等等。每次适配都需要投入大量的人力进行测试工作,那么有没有更高效、低成本的方式去解决这个问题呢?本文就介绍一种快高效、可复用的解决方案——对数据访问层做单元测试。

Mybatis测试依赖

我们项目采用的SpringBoot + Mybatis作为开发框架,大家第一想到可以用SpringBoot自带的测试注解@SpringBootTest进行测试。但是使用该注解有一个最大的弊端就是需要启动整个容器,注入全部的bean,那么一次测试就相当于启动一次应用,我们的应用启动一次就要花费近70~80秒,黄花菜都凉了。

那么有没有更好的办法,有必要注入全量的bean吗?是不是只要注入数据访问层相关的bean即可,其实官方的mybatis就给了我们这样的的解决方案。

  • 引入依赖mybatis-spring-boot-starter-test
  • 
      org.mybatis.spring.boot
      mybatis-spring-boot-starter-test
      2.3.0
      test
    
    
  • Mapper接口
  • @Mapper
    public interface CityMapper {
    
        @Select("SELECT * FROM CITY WHERE state = #{state}")
        City findByState(@Param("state") String state);
    
    }
    
  • 使用junit5的测试类
  • // 使用junit5
    @MybatisTest
    // 使用真实的数据源进行测试
    @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
    public class CityMapperTest {
    
        @Autowired
        private CityMapper cityMapper;
    
        @Test
        public void findByStateTest() {
            City city = cityMapper.findByState("CA");
            assertThat(city.getName()).isEqualTo("San Francisco");
            assertThat(city.getState()).isEqualTo("CA");
            assertThat(city.getCountry()).isEqualTo("US");
        }
    
    }
    
  • 自定义一个启动类
  • @MybatisTest 在默认情况下将会探测到带有 @SpringBootApplication 的类。 因此,由于 bean 定义的一些方法,可能会发生一些意想不到的错误,或者一些不必要的组件被装入 ApplicationContext 。 为了避免这种情况,我们可以在与测试类相同的包中创建带有 @SpringBootApplication 的类。

    package sample.mybatis.mapper;
    
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    class MapperTestApplication {
    
    }
    

  • 运行结果
  • 详细内容参考 github.com/mybatis/spr…

    但是, 上面是使用原生mybatis的测试方式,而我们项目用的是基于mybatis封装的开源框架tkMappergithub地址是https://github.com/abel533/Mapper,并不适用啊,无解,只能去看下mybatis-spring-boot-starter-test的原理。

    实现原理

    实际上mybatis-spring-boot-starter-test的实现原理很简单,代码目录结构如下:

  • @MybatisTest注解如下,引入MybatisTestContextBootstrapper测试引导程序。同时引入其他的注解,进行自动装配。
  • @AutoConfigureMybatisMybatisTest注解引入,会去找META-INF下的spring.factories,自动组装mybatis相关的bean
  • 那么基于目前的理解,我们也可以简单实现一个基于TkMapper的测试框架。

    Mapper测试框架

    我们参照mybatis原生的实现方式

  • 重新命名,内容不变
  • 修改spring.factories添加MapperAutoConfiguration
  • 使用自定义测试注解@MapperTest
  • 虽然这里有insert语句,但是测试结束,数据不会真的插入到表中,因为MapperTest注解上包含了事务注解,所以是可以反复进行测试的。

    总结

    本文分享了基于springboot+mybatis项目中针对数据访问层进行单元测试的一种方式,这种方式只注入mybatis相关的bean,快速高效的对不同类型的数据库进行测试,保证程序的正确性。

    其实,对于大多数据的程序员来说,写单元测试可能是一种负担和累赘,但是如果你的单元测试真的能够在你的项目中有其价值,那么就是值得的,千万不要为了单元测试而单元测试。

    欢迎关注个人公众号【JAVA旭阳】交流学习!

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论