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

原文鏈接:https://www.javacodegeeks.com/2018/10/parameterizedtest-null-values-cvssource.html

在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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章