欢迎访问我的GitHub
https://github.com/zq2599/blog_demos
内容:所有原创文章分类汇总及配套源码,涉及Java、Docker、Kubernetes、DevOPS等;
关于《JUnit5学习》系列《JUnit5学习》系列旨在通过实战提升SpringBoot环境下的单元测试技能,一共八篇文章,链接如下:
基本操作
Assumptions类
Assertions类
按条件执行
标签(Tag)和自定义注解
参数化测试(Parameterized Tests)进阶
综合进阶(终篇)
本篇概览本文是《JUnit5学习》系列的第七篇,前文咱们对JUnit5的参数化测试(Parameterized Tests)有了基本了解,可以使用各种数据源控制测试方法多次执行,今天要在此基础上更加深入,掌握参数化测试的一些高级功能,解决实际问题;
本文由以下章节组成:
自定义数据源
参数转换
多字段聚合
多字段转对象
测试执行名称自定义
源码下载如果您不想编码,可以在GitHub下载所有源码,地址和链接信息如下表所示:
名称 链接 备注项目主页 https://github.com/zq2599/blog_demos 该项目在GitHub上的主页
git仓库地址(https) https://github.com/zq2599/blog_demos.git 该项目源码的仓库地址,https协议
git仓库地址(ssh) git@github.com:zq2599/blog_demos.git 该项目源码的仓库地址,ssh协议
这个git项目中有多个文件夹,本章的应用在junitpractice文件夹下,如下图红框所示:
junitpractice是父子结构的工程,本篇的代码在parameterized子工程中,如下图:
自定义数据源前文使用了很多种数据源,如果您对它们的各种限制不满意,想要做更彻底的个性化定制,可以开发ArgumentsProvider接口的实现类,并使用@ArgumentsSource指定;
举个例子,先开发ArgumentsProvider的实现类MyArgumentsProvider.java:
package com.bolingcavalry.parameterized.service.impl; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.ArgumentsProvider; import java.util.stream.Stream; public class MyArgumentsProvider implements ArgumentsProvider { @Override public Stream<? extends Arguments> provideArguments(ExtensionContext context) throws Exception { return Stream.of("apple4", "banana4").map(Arguments::of); } }再给测试方法添加@ArgumentsSource,并指定MyArgumentsProvider:
@Order(15) @DisplayName("ArgumentsProvider接口的实现类提供的数据作为入参") @ParameterizedTest @ArgumentsSource(MyArgumentsProvider.class) void argumentsSourceTest(String candidate) { log.info("argumentsSourceTest [{}]", candidate); }执行结果如下:
参数转换参数化测试的数据源和测试方法入参的数据类型必须要保持一致吗?其实JUnit5并没有严格要求,而事实上JUnit5是可以做一些自动或手动的类型转换的;
如下代码,数据源是int型数组,但测试方法的入参却是double:
@Order(16) @DisplayName("int型自动转为double型入参") @ParameterizedTest @ValueSource(ints = { 1,2,3 }) void argumentConversionTest(double candidate) { log.info("argumentConversionTest [{}]", candidate); }执行结果如下,可见int型被转为double型传给测试方法(Widening Conversion):
还可以指定转换器,以转换器的逻辑进行转换,下面这个例子就是将字符串转为LocalDate类型,关键是@JavaTimeConversionPattern:
@Order(17) @DisplayName("string型,指定转换器,转为LocalDate型入参") @ParameterizedTest @ValueSource(strings = { "01.01.2017", "31.12.2017" }) void argumentConversionWithConverterTest( @JavaTimeConversionPattern("dd.MM.yyyy") LocalDate candidate) { log.info("argumentConversionWithConverterTest [{}]", candidate); }执行结果如下: