我一直在学习一些有关JUnit测试的在线课程,并且遇到了@CsvSource
的示例。以下示例效果很好。
@DisplayName("CSV input test")
@ParameterizedTest(name = DISPLAY_NAME_PLACEHOLDER + " - [" + INDEX_PLACEHOLDER + "] " + ARGUMENTS_PLACEHOLDER)
@CsvSource({
"FL, 1, 1",
"OH, 2, 2",
"MI, 3, 3"
})
void csvInputTest(String stateCode, int val1, int val2) {
System.out.println(stateCode + " - " + val1 + " - " + val2);
}
然后我开始怀疑我是否可以使用一些POJO代替参数的基础。所以我用setter和getters创建了POJO类,并将方法更改为:
void csvInputTest(StateInfo stateInfo) {
System.out.println(stateInfo.getStateCode() + " - " + stateInfo.getVal1() + " - " + stateInfo.getVal2());
}
但这导致:
org.junit.jupiter.api.extension.ParameterResolutionException: Error converting parameter at index 0: No implicit conversion to convert object of type java.lang.String to type StateInfo
我在@CsvSource
中找不到任何字段来指定任何转换器,所以我的问题是-我可以这样做吗?还是我必须坚持使用N-arguments
方法?
答案 0 :(得分:5)
The official documentation对此进行了说明:
要使用自定义聚合器,请实现ArgumentsAggregator 界面,并通过@AggregateWith批注在 @ParameterizedTest方法中的兼容参数。的结果 然后,聚合将作为 调用参数化测试时的相应参数。注意 必须将ArgumentsAggregator的实现声明为 顶层类还是静态嵌套类。
它将给出:
public class StateInfoAggregator implements ArgumentsAggregator {
@Override
public StateInfo aggregateArguments(ArgumentsAccessor arguments, ParameterContext context) {
return new StateInfo(arguments.getString(0),
arguments.getInteger(1),
arguments.getInteger(1));
}
}
@ParameterizedTest
@CsvSource({
"FL, 1, 1",
"OH, 2, 2",
"MI, 3, 3"
})
void csvInputTest(@AggregateWith(StateInfoAggregator.class) StateInfo stateInfo) {
System.out.println(stateInfo.getStateCode() + " - " + stateInfo.getVal1() + " - " + stateInfo.getVal2());
}
文档还添加了:
如果您发现自己反复声明 @AggregateWith(MyTypeAggregator.class)用于多个参数化测试 您整个代码库中的方法,您可能希望创建一个自定义的 带有@注释的注释,例如@CsvToMyType @AggregateWith(MyTypeAggregator.class)。
它将给出:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
@AggregateWith(StateInfoAggregator.class)
public @interface CsvToStateInfo {
}
@ParameterizedTest
@CsvSource({
"FL, 1, 1",
"OH, 2, 2",
"MI, 3, 3"
})
void csvInputTest(@CsvToStateInfo StateInfo stateInfo) {
System.out.println(stateInfo.getStateCode() + " - " + stateInfo.getVal1() + " - " + stateInfo.getVal2());
}