Java 如何将多维数组作为JUnit测试的参数集合返回?

Java 如何将多维数组作为JUnit测试的参数集合返回?,java,collections,multidimensional-array,junit,parameterized,Java,Collections,Multidimensional Array,Junit,Parameterized,我对Java是相当陌生的,而且我肯定是头脑发热。好吧,撇开免责声明不谈,以下是我的故事: 我在一个XML文件中有一个视频文件名和称为引用ID的补充字符串的大列表。XML如下所示: <testdata> <testcase displayName="video1" refId="vid1xxyyzz" /> <testcase displayName="video2" refId="vid2aabbcc" /> . . <testcas

我对Java是相当陌生的,而且我肯定是头脑发热。好吧,撇开免责声明不谈,以下是我的故事:

我在一个XML文件中有一个视频文件名和称为引用ID的补充字符串的大列表。XML如下所示:

<testdata>
  <testcase displayName="video1" refId="vid1xxyyzz" />
  <testcase displayName="video2" refId="vid2aabbcc" />
  .
  .
  <testcase displayName="video499" refId="vid499ffoooo" />
</testdata>
static <T> List<T> asList(T... a)
return Arrays.asList((Object[][])matrix);
按原样运行时,我得到
java.lang.IllegalArgumentException:sun.reflect.NativeConstructorAccessorImpl.newInstance0(本机方法)
的参数类型不匹配

我认为我可能使数据结构过于复杂,但现在它是这样构建的,并且似乎成功地引入了数据元素,我不知道如何重建。有人知道我做错了什么吗

下面是整个血腥的例外:

java.lang.IllegalArgumentException: argument type mismatch
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at org.junit.runners.Parameterized$TestClassRunnerForParameters.createTestUsingConstructorInjection(Parameterized.java:186)
at org.junit.runners.Parameterized$TestClassRunnerForParameters.createTest(Parameterized.java:181)
at org.junit.runners.BlockJUnit4ClassRunner$1.runReflectiveCall(BlockJUnit4ClassRunner.java:244)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:241)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.junit.runners.Suite.runChild(Suite.java:127)
at org.junit.runners.Suite.runChild(Suite.java:26)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:202)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:65)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)

我认为问题在于JUnit
@Parameters
方法需要返回一个对象数组列表,而您正在向它传递一个字符串数组列表。由于二维数组基本上只是一个数组数组,因此将二维字符串数组(
String[][]
)传递到数组中。asList()返回一个
列表,一个字符串数组列表


但是,在设置时,很容易修复,只需将传递给数组构造函数的
字符串.class
参数更改为
对象.class
,您就应该进行功能测试。

数组。asList
的定义如下:

<testdata>
  <testcase displayName="video1" refId="vid1xxyyzz" />
  <testcase displayName="video2" refId="vid2aabbcc" />
  .
  .
  <testcase displayName="video499" refId="vid499ffoooo" />
</testdata>
static <T> List<T> asList(T... a)
return Arrays.asList((Object[][])matrix);
但我感觉类型转换在运行时会失败。您可能需要将矩阵声明为

Object[][] matrix;
而不是

matrix = Array.newInstance(String.class, 2, tests.length);


(我看不出在这里使用
Array.newInstance
有什么好处,而不是只使用常规的
new

因为我无法编辑@ajb的答案和随后的评论,所以我将把最后有效的东西放在这里,放在它自己的答案中

正如建议的那样,我曾尝试将
矩阵
声明为
对象[][]
,但将表达式的其余部分和
单独留给
循环,但仍然无法工作。正是
newInstance
设置数组的方式让我陷入了麻烦。最后,我将其取出,并将相关块替换为:

    //Same as before from XMLBeans methods:
    DisplayNameReferenceIdDoc = DisplayNameReferenceIdDocument.Factory.parse(refIdFile);
    displayNameReferenceId = DisplayNameReferenceIdDoc.getDisplayNameReferenceId();
    tests = displayNameReferenceId.getTestcaseArray();

    //new, simpler Object setup strategy:
    int i;
    Object[][] matrix = new Object[tests.length][2];
    for (i = 0; i < tests.length; i++) {
        matrix[i][0] = tests[i].getDisplayName();
        matrix[i][1] = tests[i].getRefId();
    };
    return Arrays.asList(matrix);
//与前面的XMLBeans方法相同:
DisplayNameReferenceIdDoc=DisplayNameReferenceIdDocument.Factory.parse(refIdFile);
displayNameReferenceId=displayNameReferenceId.getDisplayNameReferenceId();
tests=displayNameReferenceId.getTestcaseArray();
//新的、更简单的对象设置策略:
int i;
Object[][]矩阵=新对象[tests.length][2];
对于(i=0;i
@参数化的
测试运行程序按预期将值对发送给我的测试构造函数,并且该类按照我的
@test
块的指示开始愉快地进行web服务调用


在一个完美的世界中,
XMLBeans
包本身将返回复杂行项目的多维数组,这样用户就不必进行这种争论

矩阵在何处/如何定义?异常是否还有更多信息?我将在上面添加它。在类的开头,它被定义为
静态对象矩阵也添加了异常。嗯,问题,第186行是哪一行?这很奇怪。我深入研究了
参数化.class
,它只到了第65行。让我看看我的JUnit库是否是最新的…现在开始,185..187:
私有对象createTestUsingConstructorInjection()抛出异常{return getTestClass().getOnlyConstructor().newInstance(fParameters);}
刚刚尝试了这个,但没有成功。我切换了该参数,使其类似于
matrix=Array.newInstance(Object.class,2,tests.length)和我在同一个地方得到相同的错误。当我尝试这个方法时,有一件事确实发生了变化,那就是JUnit结果在它发出嘎嘎声之前。以前看起来像
test[0:[Ljava.lang.String;@5678b14]
,现在看起来像
test[0:[Ljava.lang.Object;@4567b14]
是的,我已经怀疑我最初认为是你的问题的根本不是它,所以根据我对这个问题的评论,哪一行是186?这里是:
return getTestClass().getOnlyConstructor().newInstance(fParameters);
这将清除数据结构,但如何将该对象作为集合返回?如果声明
Object[][]矩阵;
,则
数组.asList(matrix)
应该可以工作。它将返回一个
数组列表
,其中每个元素都是一个2元素
对象[]
array。实际上,JUnit Wiki中的示例显示了声明的
@Parameters
函数类似于
public static Collection data()
,即使用
[]
Object
之后。您可能需要像这样修复
getTestParameters
声明。这似乎是正确的,但是现在我在JUnit结果中看到,每一行的第一行都被视为其自己的单个参数,并且每一行都返回
java.lang.IllegalArgumentException:参数数目错误。我将继续窃听它。谢谢!!Kyoob我会考虑改写这个,而不是<代码>数组< /Cord>类。<代码>数组< /C> >是java的“反射”特性的一部分,反射是一个可以用于专门用途的特性,但不能完成“正常”的功能。(我很少使用它)。如果您可以使用普通数组索引来做您需要做的事情,那么您应该这样做;不必要地使用
array
可能会导致问题,因为它会让您做一些不应该做的事情,而这些事情在编译时不会被捕获。