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

翻译:叩丁狼教育吴嘉俊 

在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

 

猜你喜欢

转载自blog.csdn.net/wolfcode_cn/article/details/83177950