首页 > 技术文章 > 技术文章精译 >

JUnit5中@ParameterizedTest 处理 @CvsSource中的空值

更新时间:2018-10-19 | 阅读量(2,164)

在JUnit4中测试方法参数是非常麻烦的事情(注:针对同一个方法,测试多组不同的参数值)。JUnit5中引入了大量的新的特性,让使用同一个测试方法,测试不同的参数变得非常容易。但是,这里面有一个问题值得讨论,就是测试空值的问题。 在这篇文章中,我们会讨论在JUnit5中,如何通过@CvsSource和@ValueSource为@ParameterizedTest测试传入一个空值。 ### 在@CvsSource中的空值 我们通过一个例子来引入这个问题。 假设,我们已经创建了一个类,名字叫做DateRange,这个类包含两个日期参数,用来表示一段时间。你可以通过调用DateRange的构造方法,传入至少一个日期对象,来创建一个DateRange对象。我们在构造方法中也会检查,开始时间必须在结束时间之前。 使用Junit5提供的@ParametrizedTest我们可以非常方便的进行DateRange构造器的测试: ``` @ParameterizedTest @CsvSource({ "2017-06-01, 2018-10-15", "null, 2018-10-15", "2017-06-01, null" }) void shouldCreateValidDateRange(LocalDate startDate, LocalDate endDate) { new DateRange(startDate, endDate); } @ParameterizedTest @CsvSource({ "2018-10-15, 2017-06-01", "null, null" }) void shouldNotCreateInvalidDateRange(LocalDate startDate, LocalDate endDate) { assertThrows(IllegalArgumentException.class, () -> new DateRange(startDate, endDate)); } ``` 当你运行这个测试,可能会得到类似如下的异常提示: ``` org.junit.jupiter.api.extension.ParameterResolutionException: Error converting parameter at index 0: Failed to convert String “null” to type java.time.LocalDate ``` 这是因为,虽然JUnit5中提供了多种内置的类型转换器用于将@CvsSource或者@ValueSource中的字符串转换成不同类型,但是null值是不能转化成空值的,仍然只能作为一个null字符串存在。 那我们就不能在Junit5中使用空值测试了? ### 自定义Null转换器 幸运的是,Junit5提供了非常灵活和方便的扩展方式。 默认情况下,框架使用DefaultArgumentConverter类将String转化为其他类型。我们的目标就是把@CvsSource中的null字符串变成null值,其他的字符串仍然使用默认的转化器执行转化。 为了达到这个目标,我们需要继承SimpleArgumentConverter并实现抽象方法convert()方法,在该方法中,我们检查null字符串,如果发现是null字符串,返回null值,其他的继续交给默认转化器: ``` import org.junit.jupiter.params.converter.DefaultArgumentConverter; public final class NullableConverter extends SimpleArgumentConverter { @Override protected Object convert(Object source, Class targetType) throws ArgumentConversionException { if ("null".equals(source)) { return null; } return DefaultArgumentConverter.INSTANCE.convert(source, targetType); } } ``` 注意,其中的DefaultArgumentConverter.INSTANCE.convert()方法是从JUnit5.2版本开始的。 ### 使用Null转换器 一旦我们的转换器做好,我们就可以在测试中使用@ConvertWith注解来标记我们的测试参数: ``` @ParameterizedTest @CsvSource({ "2017-06-01, 2018-10-15", "null, 2018-10-15", "2017-06-01, null" }) void shouldCreateValidDateRange(@ConvertWith(NullableConverter.class) LocalDate startDate, @ConvertWith(NullableConverter.class) LocalDate endDate) { new DateRange(startDate, endDate); } ``` 到这里,你应该已经知道如何在Junit5的参数测试中接受null值了。举一反三,类似的特殊的转换,也可以轻易实现。 原文:https://www.javacodegeeks.com/2018/10/parameterizedtest-null-values-cvssource.html
叩丁狼学员采访 叩丁狼学员采访
叩丁狼头条 叩丁狼头条
叩丁狼在线课程 叩丁狼在线课程