如何将 JUnit 参数化运行器与 varargs 构造函数一起使用?
我写了一个模型示例来说明这一点,但没有泄露任何机密。这是一个“虚拟”示例,不执行任何操作,但问题出现在测试初始化程序中。
@RunWith(Parameterized.class)
public class ExampleParamTest
{
int ordinal;
List<String> strings;
public ExampleParamTest(int ordinal, String... strings)
{
this.ordinal = ordinal;
if (strings.length == 0)
{
this.strings = null;
}
else
{
this.strings = Arrays.asList(strings);
}
}
@Parameters
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][] {
{0, "hello", "goodbye"},
{1, "farewell"}
});
}
@Test
public void doTest() {
Assert.assertTrue(true);
}
}
基本上我有一个测试构造函数,它接受本地列表变量的多个参数,并且我想通过数组初始化程序来填充它。测试方法将正确处理本地列表变量 - 我已删除此逻辑以简化测试。
当我写这篇文章时,我的 IDE 对语法没有任何抱怨,并且测试类的构建没有任何编译错误。然而,当我运行它时,我得到:
doTest[0]:
java.lang.IllegalArgumentException: wrong number of arguments
at java.lang.reflect.Constructor.newInstance(Unknown Source)
doTest[1]:
java.lang.IllegalArgumentException: argument type mismatch
at java.lang.reflect.Constructor.newInstance(Unknown Source)
这里到底出了什么问题,以及如何正确使用这个模式?
I wrote a mockup example to illustrate this without exposing anything confidential. It's a "dummy" example which does nothing, but the problem occurs in the test initialiser.
@RunWith(Parameterized.class)
public class ExampleParamTest
{
int ordinal;
List<String> strings;
public ExampleParamTest(int ordinal, String... strings)
{
this.ordinal = ordinal;
if (strings.length == 0)
{
this.strings = null;
}
else
{
this.strings = Arrays.asList(strings);
}
}
@Parameters
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][] {
{0, "hello", "goodbye"},
{1, "farewell"}
});
}
@Test
public void doTest() {
Assert.assertTrue(true);
}
}
Basically I have a test constructor which accepts multiple arguments for a local list variable and I want to populate this through an array initialiser. The test method will handle the local list variable correctly - I have removed this logic to simplify the test.
When I write this, my IDE has no complaints about syntax and the test class builds without any compile errors. However when I run it, I get:
doTest[0]:
java.lang.IllegalArgumentException: wrong number of arguments
at java.lang.reflect.Constructor.newInstance(Unknown Source)
doTest[1]:
java.lang.IllegalArgumentException: argument type mismatch
at java.lang.reflect.Constructor.newInstance(Unknown Source)
What exactly has gone wrong here, and how do I correctly use this pattern?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
现在无法测试它,但我想,如果您使用可变参数调用方法或构造函数,则必须使用数组而不是变量值列表来调用它。
如果我是对的,那么这应该可行:
一些解释
在源代码级别,我们可以编写
编译器会将其转换为字符串数组。 JUnit 使用反射和调用 API,从这个角度来看,构造函数签名是
So 要调用构造函数 - 这就是 JUnit 在内部所做的 - 您必须传递一个整数和一个字符串数组。
Can't test it right now but I guess, if you invoke a method or a constructor with variable arguments, you have to invoke it with an array instead of a variable list of values.
If I'm right, then this should work:
Some explanation
On source code level, we can write
The compiler will convert this to an array of Strings. JUnit uses the reflection and invocation API, and from this perspective, the constructors signature is
So to invoke the constructor - and that's what JUnit is doing internally - you have to pass an integer and a String array.
@marcphillip 在此 JUnit 功能请求 中给出的解决方法目前效果很好:
更新:我添加了此调整,以便在最后一个逗号后没有提供任何内容时提供一个空数组:更新2: > 我意识到这是不需要的:只需省略尾随逗号(我认为这是强制性的)即可传递空的可变参数数组。
The workaround given by @marcphillip in this JUnit feature request works great for now:
Update: I added this tweak to give an empty array when there is nothing provided after the last comma: Update2: I realized this is not needed: Just leave off the trailing comma (which I'd assumed was mandatory) in order to pass in an empty vararg array.