好的,这将是一个奇怪的答案,但它很有效,而且做起来很有趣。
第一件事:你的方式是不可能的。不是因为 JUnit 或任何相关 API,而是因为 Java -有效的注解类型元素(注解参数只能是原始的、字符串、类、枚举、其他注解和所有这些的数组)。
第二件事:我们可以绕过第一件事。检查这个:
@ArraySources(
arrays = {
@ArraySource(array = {1, 2, 3}),
@ArraySource(array = {4, 5, 6}),
@ArraySource(array = {7, 8, 9})
}
)
正如它所说,注释可以有其他注释作为参数,以及这些注释的数组,所以我们在这里使用这两个规则。
第三件事:这有什么帮助?我们可以添加自己的注解 + 参数提供者,JUnit 5 可以通过这种方式进行扩展。
两个注释:
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@ArgumentsSource(ArrayArgumentsProvider.class)
public @interface ArraySources {
ArraySource[] arrays();
}
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ArraySource {
int[] array() default {};
}
基于注释的参数提供者:
public class ArrayArgumentsProvider implements ArgumentsProvider, AnnotationConsumer<ArraySources> {
private List<int[]> arguments;
public void accept(ArraySources source) {
List<ArraySource> arrays = Arrays.asList(source.arrays());
this.arguments = arrays.stream().map(ArraySource::array).collect(Collectors.toList());
}
public Stream<? extends Arguments> provideArguments(ExtensionContext context) {
return this.arguments.stream().map(Arguments::of);
}
}
以及使用这些的最终测试:
public class ArraySourcesTest {
@ParameterizedTest
@ArraySources(
arrays = {
@ArraySource(array = {1, 2, 3}),
@ArraySource(array = {4, 5, 6}),
@ArraySource(array = {7, 8, 9})
}
)
void example(int[] array) {
System.out.println(Arrays.toString(array));
System.out.println("Test Over");
}
}
/* Output
[1, 2, 3]
Test Over
[4, 5, 6]
Test Over
[7, 8, 9]
Test Over
*/
你提到@MethodSource
的很复杂,好吧,所以我认为我在这件事上失败了,但它确实有效。它可以明显地简化和增强(比如将注释参数命名为默认值 - 值 - 我只是int
为了展示这个想法)。不确定您是否可以使用现有功能(ArgumentsProvider
和ArgumentSources
)实现相同的功能,但这看起来更具体(您知道您正在使用数组)并显示扩展 JUnit5 的可能性,在其他情况下可能有用。