PowerMock:正确使用Whitebox.invokeMethod(...)作为将Object []作为参数的方法

时间:2012-11-01 21:30:51

标签: java unit-testing junit powermock white-box

private boolean isEmpty(Object[] array) {
    if (array == null || array.length == 0) 
        return true;
    for (int i = 0; i < array.length; i++) {
    if (array[i] != null) 
        return false;
    }           

    return true;
}

@Test
public void testIsEmpty() {
        //where is an instance of the class whose method isEmpty() I want to test.
    try {
        Object[] arr = null;
        assertTrue((Boolean)(Whitebox.invokeMethod(where, "isEmpty", new Class<?>[]{Object[].class},  arr)));

        arr = new Object[0];
        assertTrue((Boolean)(Whitebox.invokeMethod(where, "isEmpty", new Class<?>[]{Object[].class}, arr)));

        arr = new Object[]{null, null};
        assertTrue((Boolean)(Whitebox.invokeMethod(where, "isEmpty", new Class<?>[]{Object[].class}, arr)));

        arr = new Object[]{1, 2};
        assertFalse((Boolean)(Whitebox.invokeMethod(where, "isEmpty", new Class<?>[]{Object[].class}, arr)));
    } catch (Exception e) {
        fail(e.getMessage());
    }       
}

问题:java.lang.AssertionError:参数数量错误

研究: 1.最初,我试过:         invokeMethod(对象测试,String methodToExecute,Object ...参数)

第2次,第3次和第4次invokeMethod()失败了。 (错误:找不到给定参数的方法)

我认为这可能是由于PowerMock没有推断出正确方法的问题;因此,我切换到:         invokeMethod(对象测试,String methodToExecute,Class [] argumentTypes,Object ... arguments)

  1. 父类有一个isEmpty()方法,该方法在子类中具有完全重复的isEmpty()方法。 (遗留代码)没有其他不同签名的isEmpty()方法。有许多方法采用参数,但没有其他方法采用Object [](例如,没有采用Integer []作为参数的方法)。

  2. 在上面的第二个assertTrue语句之前,更改为arr = new Object [1]会使该断言语句通过。

  3. 非常感谢任何帮助。谢谢!

1 个答案:

答案 0 :(得分:4)

认为它应该通过将参数转换为Object来工作,以使Java将其作为单个参数,而不是与Object...对应的参数数组:

Whitebox.invokeMethod(where, "isEmpty", new Class<?>[]{Object[].class}, (Object) arr);

测试用例:

public static void main(String[] args) {
    foo(new Object[] {"1", "2"}); // prints arg = 1\narg=2
    foo((Object) (new Object[] {"1", "2"})); // prints args = [Ljava.lang.Object;@969cccc
}

private static void foo(Object... args) {
    for (Object arg : args) {
        System.out.println("arg = " + arg);
    }
}