Java – how do I use a JUnit parameterized runner with a varargs constructor?
I wrote a model example to illustrate this without divulging any confidential information This is a "virtual" example that does nothing, but the problem occurs in the test initializer
@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 that accepts multiple parameters of a local list variable, and I want to populate it with an array initializer The test method will handle local list variables correctly – I have removed this logic to simplify the test
When I wrote this article, my ide had no complaints about syntax and test class construction, and there were no compilation errors But 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's wrong here and how can I use this model correctly?
Solution
I can't test it now, but I think if you call a method or constructor with variable parameters, you must use an array instead of a list of variable values to call it
If I'm right, then this should work:
@Parameters
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][] {
{0,new String[]{"hello","goodbye"}},new String[]{"farewell"}}
});
}
Some explanation
At the source level, we can write
test = ExampleParamTest(0,"one","two");
The compiler converts it to a string array JUnit uses reflection and call APIs. From this point of view, constructor signatures are
public ExampleParamTest(int i,String[] strings);
Therefore, to call the constructor - which is what JUnit does internally - you must pass an integer and a string array
