如何高效测试Mybatis?(xxxMapper)

一、背景

  • 虽然我们可以借助插件来高效生成xxxDO、xxxMapper.java、xxxMapper.xml,但我们还需要对其进行修改。而在修改的过程中,我们可能会漏了逗号,或者类的字段类型与表的列类型不匹配,这都会导致增删改查失败。
  • 每次失败重新启动应用的话,会增加测试的时间开销。(JRebel热部署插件虽然能热部署xml文件,但有时候会失效。)
  • 因此,在进行controller-service-dao功能测试之前,我们要先对dao层进行单元测试。

二、对Dao层进行单元测试

1 低效的方式

1.1 使用@SpringBootTest:

@SpringBootTest
class UserMapperTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    void insert() {
        UserDO user = new UserDO();
        user.setName("John");
        user.setAge(30);
        userMapper.insert(user);

        assertNotNull(user.getId(), "Insert should generate ID");

        UserDO retrievedUser = userMapper.selectById(user.getId());
        assertNotNull(retrievedUser, "User should be retrieved after insertion");
        assertEquals("John", retrievedUser.getName(), "Name should match");
        assertEquals(30, retrievedUser.getAge(), "Age should match");
    }
	
	...
}
  • 低效的原因:使用@SpringBootTest会加载整个应用的上下文。

1.2 其他低效的方式

  • 把整个SpringBoot应用跑起来,通过Postman进行测试。
    • 企业级应用,要么本地起不来,要不跑一次要若干分钟。这么测试,又要加班了…

2 高效的方式

  • SpringBoot整合Mybatis引入了这个依赖:
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.3.2</version>
</dependency>
  • 同理,也有对应的测试依赖:
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter-test</artifactId>
    <version>2.3.2</version>
</dependency>

官方文档

2.1 示例(报错:Failed to replace DataSource with an embedded database for tests)

@MybatisTest
class UserMapperSimpleTest {
    @Autowired
    private UserMapper userMapper;

    @Test
    void deleteById() {
        UserDO user = new UserDO();
        user.setName("Alice");
        user.setAge(25);
        userMapper.insert(user);

        Integer userId = user.getId();
        assertNotNull(userId, "Insert should generate ID");

        userMapper.deleteById(userId);

        UserDO deletedUser = userMapper.selectById(userId);
        assertNull(deletedUser, "User should be deleted");
    }
}
  • 报错:Caused by: java.lang.IllegalStateException: Failed to replace DataSource with an embedded database for tests. If you want an embedded database please put a supported one on the classpath or tune the replace attribute of @AutoConfigureTestDatabase.
  • 原因:在测试中 Spring Boot 尝试替换数据源为一个内嵌的数据库,但是它找不到一个支持的内嵌数据库。

2.2 解决办法

  • 配置支持的内嵌数据库(很麻烦,又要建表,又要构造数据)
  • 禁用自动配置的数据源替换(很方便,一方面本地环境操作的是日常数据库,另一方面MyBatis 测试是事务性的,默认在每次测试结束时回滚)
2.2.1 禁用自动配置的数据源替换
@MybatisTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class UserMapperSimpleTest {
    @Autowired
    private UserMapper userMapper;

    @Test
    void insert() {
        UserDO user = new UserDO();
        user.setName("John");
        user.setAge(30);
        userMapper.insert(user);

        assertNotNull(user.getId(), "Insert should generate ID");

        UserDO retrievedUser = userMapper.selectById(user.getId());
        assertNotNull(retrievedUser, "User should be retrieved after insertion");
        assertEquals("John", retrievedUser.getName(), "Name should match");
        assertEquals(30, retrievedUser.getAge(), "Age should match");
    }

    @Test
    void deleteById() {
        UserDO user = new UserDO();
        user.setName("Alice");
        user.setAge(25);
        userMapper.insert(user);

        Integer userId = user.getId();
        assertNotNull(userId, "Insert should generate ID");

        userMapper.deleteById(userId);

        UserDO deletedUser = userMapper.selectById(userId);
        assertNull(deletedUser, "User should be deleted");
    }

}
  • 我测试了下,@Service标注的类确实没法注入了。
@MybatisTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class UserMapperSimpleTest {
    @Autowired
    private UserMapper userMapper;

    @Autowired(required = false)
    private IUserService userService;

    @Test
    void testUserServiceNotInjected() {
        assertNull(userService, "User service should not be injected");
    }

    @Test
    void testUserMapperInjected() {
        assertNotNull(userMapper, "User mapper should be injected");
    }
}
  • 而如果是@SpringBootTest,就会把@Service标注的类也注入到容器中。
  • 14
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: MyBatis是一种优秀的持久层ORM框架,它可以简化开发人员对关系数据库的使用。使用MyBatis有以下几个原因:首先,MyBatis提供了灵活的SQL映射,使得开发人员可以直接编写SQL语句,灵活地操作数据库。其次,MyBatis具有良好的性能,它采用了对SQL语句进行预编译和缓存的优化技术,可以减少数据库访问的开销。此外,MyBatis还支持动态SQL语句的编写,可以根据实际需求来动态生成SQL语句,提高开发效率。最后,MyBatis具有良好的扩展性,可以与其他框架和工具无缝集成,如Spring等。综上所述,使用MyBatis可以简化开发人员对数据库的操作,提高开发效率,并且具有良好的性能和扩展性。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [1、mybatis是什么?为什么要用mybatis?](https://blog.csdn.net/chaizepeng/article/details/119384531)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [什么是Mybatis,为什么要学习Mybatismybatis与hibernate区别](https://blog.csdn.net/qq_44543508/article/details/97007064)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [[Java]为什么要使用MyBatis](https://blog.csdn.net/loongkingwhat/article/details/88393643)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值