代码之家  ›  专栏  ›  技术社区  ›  Adam Burley

如何使用带有varargs构造函数的JUnit参数化运行程序?

  •  6
  • Adam Burley  · 技术社区  · 16 年前

    @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)
    

    这里到底出了什么问题,如何正确使用这个模式?

    1 回复  |  直到 16 年前
        1
  •  11
  •   Andreas Dolk    16 年前

    现在无法测试它,但我猜,如果用变量参数调用方法或构造函数,则必须用数组而不是变量值列表来调用它。

    如果我是对的,那么这应该有用:

    @Parameters
     public static Collection<Object[]> data() {
      return Arrays.asList(new Object[][] {
        {0, new String[]{"hello", "goodbye"}},
        {1, new String[]{"farewell"}}
      });
     }
    

    一些解释

    test = ExampleParamTest(0, "one", "two");
    

    编译器将把它转换成一个字符串数组。JUnit使用反射和调用API,从这个角度来看,构造函数签名是

    public ExampleParamTest(int i, String[] strings);
    

    因此,要调用构造函数(JUnit内部就是这么做的),必须传递一个整数和一个字符串数组。