为什么在给定 List<List<Any>> 时为参数化 JUnit 测试抛出 IllegalArgumentException,但适用于 List<Array<Any>>
Why is IllegalArgumentException thrown for a Parameterized JUnit test when given List<List<Any>>, but works with List<Array<Any>>
在调试参数化测试时,我意识到如果参数作为列表列表 (List<List<Any>>
) 传递,则测试不会 运行,但可以很好地处理数组列表 ( List<Array<Any>>
).
示例类:
import com.google.common.truth.Truth
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
class TestWithList(val input: List<Int>, val output: Int) {
companion object {
@JvmStatic
@Parameterized.Parameters
fun data(): List<List<Any>> =
listOf(
listOf(
listOf(1, 4, 3, 2),
4
)
)
}
@Test
fun `empty test`() {
Truth.assertThat(true).isTrue()
}
}
投掷
IllegalArgumentException: wrong number of arguments
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
class TestWithArray(val input: List<Int>, val output: Int) {
companion object {
@JvmStatic
@Parameterized.Parameters
fun data(): List<Array<Any>> =
listOf(
arrayOf(
listOf(1, 4, 3, 2),
4
)
)
}
@Test
fun `empty test`() {
assertThat(true).isTrue()
}
}
完美运行。
为什么传递 List
会传递错误数量的参数?
我不熟悉 JUnit 的参数化测试。但是,我确实找到了 this。如果您查看方法签名:
public static Collection<Object[]> data()
在 Kotlin 中,即:
fun data() : Collection<Array<Any>>
您会看到它是一个集合,包含一个对象数组。 List
是一个集合,但 List
不是 Array
。它是一个二维系统,其中第二个维度包含您要传递的参数,包括长度。
由于他们在文档中使用了数组,因此我建议您这样做。
最近,他们引入了单一参数。签名看起来像这样:
@Parameters
public static Iterable<? extends Object> data()
同样,List 是一个 Iterable。但是,在您的情况下,这是您最终在没有数组的情况下调用的那个。
因此,您将一个参数传递给了一个双参数构造函数,这引发了异常。你传递了一个 Iterable>,它不是 Collection<Array<Any>>
。这意味着您反而最终创建了一个适用于单个参数的系统。由于构造函数有两个参数,因此会出现异常。您传递了一个参数(列表),但您需要两个参数。
这就是为什么使用数组有效而列表无效的原因;如果你使用一个列表,它假设你有一个单一的参数构造函数,而对于一个数组,它需要多个。据我所知,JUnit 不支持多参数构造函数的列表而不是数组。
TL;DR: 数组起作用而列表不起作用的原因是因为它认为 List 是单参数构造函数的参数,而与数组一样,它可以是任意数量的参数。
在调试参数化测试时,我意识到如果参数作为列表列表 (List<List<Any>>
) 传递,则测试不会 运行,但可以很好地处理数组列表 ( List<Array<Any>>
).
示例类:
import com.google.common.truth.Truth
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
class TestWithList(val input: List<Int>, val output: Int) {
companion object {
@JvmStatic
@Parameterized.Parameters
fun data(): List<List<Any>> =
listOf(
listOf(
listOf(1, 4, 3, 2),
4
)
)
}
@Test
fun `empty test`() {
Truth.assertThat(true).isTrue()
}
}
投掷
IllegalArgumentException: wrong number of arguments
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
class TestWithArray(val input: List<Int>, val output: Int) {
companion object {
@JvmStatic
@Parameterized.Parameters
fun data(): List<Array<Any>> =
listOf(
arrayOf(
listOf(1, 4, 3, 2),
4
)
)
}
@Test
fun `empty test`() {
assertThat(true).isTrue()
}
}
完美运行。
为什么传递 List
会传递错误数量的参数?
我不熟悉 JUnit 的参数化测试。但是,我确实找到了 this。如果您查看方法签名:
public static Collection<Object[]> data()
在 Kotlin 中,即:
fun data() : Collection<Array<Any>>
您会看到它是一个集合,包含一个对象数组。 List
是一个集合,但 List
不是 Array
。它是一个二维系统,其中第二个维度包含您要传递的参数,包括长度。
由于他们在文档中使用了数组,因此我建议您这样做。
最近,他们引入了单一参数。签名看起来像这样:
@Parameters
public static Iterable<? extends Object> data()
同样,List 是一个 Iterable。但是,在您的情况下,这是您最终在没有数组的情况下调用的那个。
因此,您将一个参数传递给了一个双参数构造函数,这引发了异常。你传递了一个 Iterable>,它不是 Collection<Array<Any>>
。这意味着您反而最终创建了一个适用于单个参数的系统。由于构造函数有两个参数,因此会出现异常。您传递了一个参数(列表),但您需要两个参数。
这就是为什么使用数组有效而列表无效的原因;如果你使用一个列表,它假设你有一个单一的参数构造函数,而对于一个数组,它需要多个。据我所知,JUnit 不支持多参数构造函数的列表而不是数组。
TL;DR: 数组起作用而列表不起作用的原因是因为它认为 List 是单参数构造函数的参数,而与数组一样,它可以是任意数量的参数。