跳转到内容

使用 Trantor 进行单元测试

背景

在 Trantor 中,访问数据依赖模型元信息,即需要依赖 MetaStore 和 DataStore 两个服务分别存储元信息和协议转换以访问数据。

在此之前,我们想在一个单元测试中访问数据,需要在本地启动一套完整 trantor 环境,并且手动清理测试中产生的数据。这个操作比较繁琐,并且不符合单元测试定义,因此我们提供了单元测试特性支持。

特性

✅ Mock MetaStore,在测试过程中不依赖 MetaStore 服务。

✅ 测试完成后自动清理测试数据。

✅ 使用@ActiveModule按需注册模块,如果一个业务模块依赖了很多其他模块,在测试中我们也会注册依赖模块的模型,并在 db 里建立对应的 schema,这样会导致测试的执行速度下降,如果只需要依赖少量模块,建议注册模块

第一个单元测试

Maven依赖

首先需要依赖一个测试 jar 包,test-framework已经集成了 spring-boot-starter-test ,不需要依赖其他测试框架,开箱即用。(若是使用插件创建的impl模块,已添加依赖)

<dependency>
<groupId>io.terminus.trantor</groupId>
<artifactId>test-framework</artifactId>
<scope>test</scope>
</dependency>

环境变量

启动DataStore 服务( 可以使用 trantor-cli 提供的 DataStore )

由于测试会启动一个 spring context,因此会初始化一些 bean,这些 bean 需要配置一些环境变量,比如 DS_PORTUSER_MOCKACL_MOCK 等。

Trantor 没有限制注入环境变量的方式,可以使用@SpringBootTest 或 新建一个专门用于测试的 application-test.yml,也可以用别的方式,这里以application-test.yml为例

DS_PORT: 8081
USER_MOCK: true
ACL_MOCK: true
DUBBO_ENABLED: false
trantor:
mainModule: base

声明@ActiveProfiles("test")即可:

@RunWith(TSpringRunner.class)
@SpringBootTest
@ActiveProfiles("test")
public class UnitTest {
}

注册模块

如果在一个或者一组测试中,只需要依赖少量模块,建议声明注解@ActiveModule

  • 声明在类上:当前测试只使用@ActiveModule 注册的模块资源
  • 声明在方法上:当前测试方法只使用@ActiveModule 注册的模块资源

编写用例

❗️我们使用TSpringRunner 代替 spring-test 提供的 SpringRunner,其余配置与普通 spring-test 一致。

@RunWith(TSpringRunner.class) //❗️io.terminus.trantorframework.test.TSpringRunner
@SpringBootTest
@ActiveProfiles("test")
@ActiveModule("base") //❗️模块key
public class UnitTest {
@Autowired
private CompanyRepo companyRepo;
@Test
//❗️@ActiveModule("base"),可以声明在方法上
public void testCreate() {
Company company = companyRepo.createWithRelation(new Company());
assertThat(company.getName()).isEmpty();
}
}

使用插件快速创建

写单测应聚焦于单测逻辑本身,而非如何定义Trantor单测,通过插件创建单元测试可用且高效:

  • 若存在application-test.yml,插件会优先使用@ActiveProfiles(test),否则会将trantor env的环境变量自动注入@SpringBootTest
  • 支持@ActiveModule,插件会列出当前模块以及依赖模块,可多选。
  • 可多选测试资源,创建多个方法。

插件创建

已知问题

由于 DataStore 的执行逻辑全部在服务端,逻辑又比较复杂,因此这版本测试还是依赖 DataStore,后面版本 DataStore Client 重做以后考虑支持完整的 mock。