使用数据库作为接口还怕难以测试?@DataJpaTest 稳稳接住

单元测试

Spring Boot 为测试应用程序片段提供了很多名称如 @...Test 这样的注解,他们会为测试片段准备好自动配置注解,测试 JPA 则提供了 @DataJpaTest,使用起来很方便。

首先,确认添加测试数据库依赖,Spring Data JPA 默认使用 h2。

 

xml

代码解读

复制代码

<dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>test</scope> </dependency>

然后,在测试类上添加 @DataJpaTest 注解,这个注解用于加载 Spring Data JPA 所需上下文,包括扫描 Repository,以及默认集成 h2 作为测试数据库。

最后,就可以对 Repository 进行局部测试了,这样做的好处是可以独立测试 Repository,不需要连接外部数据库,也不需要加载所有 Bean。@DataJpaTest 默认是开启 SQL 日志打印的(spring.jpa.show-sql),可以直接在终端查看 SQL 执行过程:

 

sql

代码解读

复制代码

Hibernate: select hotelfollo0_.id as id1_1_, hotelfollo0_.create_time as create_t2_1_, hotelfollo0_.create_user as create_u3_1_, hotelfollo0_.update_time as update_t4_1_, hotelfollo0_.update_user as update_u5_1_, hotelfollo0_.hotel_id as hotel_id6_1_ from followed_hotel hotelfollo0_ Hibernate: select nextval ('fendo_generator') Hibernate: insert into followed_hotel (create_time, create_user, update_time, update_user, hotel_id, id) values (?, ?, ?, ?, ?, ?) Hibernate: select hotelfollo0_.id as id1_1_, hotelfollo0_.create_time as create_t2_1_, hotelfollo0_.create_user as create_u3_1_, hotelfollo0_.update_time as update_t4_1_, hotelfollo0_.update_user as update_u5_1_, hotelfollo0_.hotel_id as hotel_id6_1_ from followed_hotel hotelfollo0_

审计测试

用户配置在架构设计上是与数据访问是分离的,测试上也是如此,不应在数据访问层完成,隔离审计用户获取的方式,可以使用 MockBean

上文提到的 ModifierUserAware 获取当前请求数据访问用户就可以这样实现测试隔离:

整理了这份面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题

需要全套面试笔记【点击此处】即可免费获取

java

代码解读

复制代码

@MockBean private ModifierUserAware modifierUserAware; @BeforeEach public void testModifierUser() { changeModifierUser(DEFAULT_USER_CODE); } private void changeModifierUser(String userCode) { Mockito.when(modifierUserAware.getCurrentAuditor()).thenReturn(Optional.of(userCode)); }

testModifierUser 添加了 @BeforeEach,用于执行数据访问测试前构造访问用户信息,测试不同用户访问数据,就可以调用 changeModifyUser 修改。

最后,实现测试数据的结构就变成了这样,构造测试数据、修改访问用户、再次构造测试数据、执行 Repository 数据访问、断言验证结果。

 

java

代码解读

复制代码

@DisplayName(xxx) @Test public void testxxx() { mockDataxxx(); changeModifierUser(xxx); mockDataxxx(); xxxRepository.xxx() Assertions.assertxxx(); }

集成测试

这里对集成测试的理解是连接外部服务,使用测试环境(与生产环境相同的数据库)进行测试。集成测试可用于 H2 在语法上以及 JPA 对不同方言的支持上的差异。

在测试类 @DataJpaTest 同时添加这个注解,表示不使用默认测试数据库替换,会加载外部配置中的数据连接配置。

 

java

代码解读

复制代码

@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)

数据业务测试

根据数据接口约定编写测试数据 SQL(这里表名做了混淆),在 test/resources/sql 里约定目录结构,schema 存储表结构,data 存储测试数据。

测试类添加 @DataJpaTest 注解,完成数据接口测试编写:

 

java

代码解读

复制代码

@Test @Sql({ "/sql/schema/table_1706602772847_schema.sql", "/sql/data/table_1706602772847_data.sql" }) @DisplayName("测试xxx") public void testLabelHitxxxWithPageSizeFive() { List<LabelHitxxx> labelHitxxx = labelHitxxxRepository.labelHitPersons(5, 5); Assertions.assertEquals(labelHitxxx.size(), 7); long resultSum = labelHitxxx.stream() .map(LabelHitxxx::getxxx) .distinct() .count(); Assertions.assertEquals(resultSum, 4); }

这样,没有外部数据库对接,依然可以进行本系统功能验证,并且可以实现本地运行,不依赖数据库连接。

这才是 ORM 该有的测试,JPA Test。

  • 8
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值