下面是JUnit 5中的参数化测试示例。
@ParameterizedTest
@MethodSource("generalDataset")
fun shouldCreateItem(color: String, size: String) {
val item = Item(color, size)
assertThat(item.color).isEqualTo(color)
}
@JvmStatic
fun generalDataset() =
Stream.of(
arguments("blue", "S"),
arguments("red", "S"),
arguments("green", "S"),
arguments("blue", "L"),
arguments("red", "L"),
arguments("green", "L")
)确保generalDataset是两个集合{"blue", "red", "green"} x {"S", "L"}的乘积。
为了避免重复,最好像下面的伪代码那样显式地描述它
@ParameterizedTest
@MethodSource("colorDataset" %MULTIPLY% "sizeDataset")
fun shouldCreateItem(color: String, size: String) {
val item = Item(color, size)
assertThat(item.color).isEqualTo(color)
}
@JvmStatic
fun colorDataset() =
Stream.of(
arguments("blue"),
arguments("red"),
arguments("green")
)
@JvmStatic
fun sizeDataset() =
Stream.of(
arguments("S"),
arguments("L")
)是否有可能在JUnit 5中实现类似的测试(带乘源的参数化测试)?
发布于 2022-02-07 14:16:49
您可以指定一个方法作为源。在这种方法中,您可以提供笛卡尔乘积。
简单的例子:
@ParameterizedTest
@MethodSource("provideStringsForIsBlank")
...
private static Stream<Arguments> provideStringsForIsBlank() {
return Stream.of(
Arguments.of(null, true),
Arguments.of("", true),
Arguments.of(" ", true),
Arguments.of("not blank", false)
);
}发布于 2022-02-07 23:33:55
如果您想避免使用外部库,我编写了一些代码来完成笛卡儿产品,测试不多,但很简单,而且很有效。
编辑:我优化了代码以记忆递归调用。
class SomeTestClass {
@ParameterizedTest
@MethodSource("SomeTestClassKt#provideSomeData")
fun someTest(first: String, second: Boolean, third: Int) {
println("first = $first, second = $second, third = $third")
}
}
private fun provideSomeData(): Stream<Arguments> {
return cartesianArguments(
listOf("Product1", "Product2", "Product3"),
listOf(true, false),
listOf(1, 5, 12)
)
}
inline fun <reified T> cartesianArguments(vararg input: List<T>): Stream<Arguments> {
return cartesianRecurrence(input.toList())
.stream()
.map { Arguments.of(*it.toTypedArray()) }
}
fun <T> cartesianRecurrence(input: List<List<T>>): List<List<T>> {
if (input.size < 2)
return input.flatten().map { listOf(it) }
val result = cartesianRecurrence(input.tail)
return input.head.flatMap { headElement ->
result.map { headElement + it }
}
}
operator fun <T> T.plus(tail: List<T>): List<T> {
val list = ArrayList<T>(1 + tail.size)
list.add(this)
list.addAll(tail)
return list
}
val <T> List<T>.tail: List<T>
get() = drop(1)
val <T> List<T>.head: T
get() = first()这就产生了结果:
first = Product1, second = true, third = 1
first = Product1, second = true, third = 5
first = Product1, second = true, third = 12
first = Product1, second = false, third = 1
first = Product1, second = false, third = 5
first = Product1, second = false, third = 12
first = Product2, second = true, third = 1
first = Product2, second = true, third = 5
first = Product2, second = true, third = 12
first = Product2, second = false, third = 1
first = Product2, second = false, third = 5
first = Product2, second = false, third = 12
first = Product3, second = true, third = 1
first = Product3, second = true, third = 5
first = Product3, second = true, third = 12
first = Product3, second = false, third = 1
first = Product3, second = false, third = 5
first = Product3, second = false, third = 12https://stackoverflow.com/questions/71019876
复制相似问题