如何使用Powermock的Whitebox.invokeMethod(Object instance, Object...参数)当我的第一个方法参数是字符串类型时?



我不想显式地命名我在invokeMethod()参数中调用的方法。Powermock提供了一个重载的invokeMethod(),它根据传递的参数推断方法。

invokeMethod(Object instance, Object... arguments)

我遇到的问题是,我的第一个参数是类型String。这将使用签名

调用invokeMethod()
invokeMethod(Object instance, String methodToExecute, Object... arguments)

这是一个测试模型…

@Test
public void thisIsATest() throws Exception{
    TheClassBeingTested myClassInstance = new TheClassBeingTested();
    String expected = "60";
    String firstArgument = "123A48"; 
    ReturnType returnedTypeValue = Whitebox.invokeMethod(myClassInstance, firstArgument, AnEnum.TypeA);
    String actual = returnedTypeValue.getTestedField();
    assertEquals("Expected should be actual when AnEnum is TypeA", expected, actual);
}

这给了我错误,

org.powermock.reflect.exceptions.MethodNotFoundException: No method found with name '123A48' with parameter types: [ AnEnum ] in class TheClassBeingTested.`

我通过将第一个参数的类型更改为Object来使其工作,但这对我来说感觉很脏。

@Test
public void thisIsATest() throws Exception{
    TheClassBeingTested myClassInstance = new TheClassBeingTested();
    String expected = "60";
    Object firstArgument = "123A48"; 
    ReturnType returnedTypeValue = Whitebox.invokeMethod(myClassInstance, firstArgument, AnEnum.TypeA);
    String actual = returnedTypeValue.getTestedField();
    assertEquals("Expected should be actual when AnEnum is TypeA", expected, actual);
}

是否有一种正确的方法来传递String类型作为第一个参数,而不是硬编码我的方法名称到invokeMethod()调用?我在Powermock文档或论坛中没有找到解决这个问题的任何内容,但肯定不可能那么罕见。

您真正需要做的是查看thecclassbeingsted .java。错误消息告诉您问题出在白盒上。invoke方法无法在它通过反射创建的classbeingtesting中找到名为"123A48"的方法。在这种情况下,我认为你选择的invokeMethod正在寻找参数(对象classUnderTest,字符串methodName,对象…参数)。

试试这样写:

public class TheClassBeingTested {
    private String foo;
    public void setFoo(String fooValue) {
        foo = fooValue;
    }
    public String getFoo() {
        return foo;
    }
}

然后你可以像这样用Whitebox测试:

public class TheClassBeingTestedTester {
    @Test
    public void thisIsATest() throws Exception {
        TheClassBeingTested toBeTested = new TheClassBeingTested();
        String theMethodToTest = "setFoo";
        String expectedFooValue = "foo bar baz";
        ReturnType returnedTypeValue = Whitebox.invokeMethod(toBeTested, theMethodToTest, expectedFooValue);
        String actual = returnedTypeValue.getTestedField();
        assertEquals("Expected " + expected + " but found " + actual, expected, actual);
     }
}

希望对你有帮助。

…编辑后的回复

由于我没有仔细阅读你的问题,同时也在从事其他开发工作,我错过了重点。

在这种情况下,我将对您的测试进行以下修改,以避免调用方法歧义问题:
@Test
public void thisIsATest() throws Exception{
    TheClassBeingTested myClassInstance = new TheClassBeingTested();
    String expected = "60";
    Object[] parameters = new Object[]{"123A48", AnEnum.TypeA};
    ReturnType returnedTypeValue = Whitebox.invokeMethod(myClassInstance, parameters);
    String actual = returnedTypeValue.getTestedField();
    assertEquals("Expected should be actual when AnEnum is TypeA", expected, actual);

}

这样,歧义就被消除了,这样invokeMethod(Object instance, Object…)参数)将只看到方法签名告诉编译器期望的对象数组。尽管String是一个对象,但在方法签名反射中,java.lang.reflect会遵循它认为您试图告诉它使用的第二个签名,而不是您希望它使用的第二个签名。

希望这个答案更符合你的要求。

相关内容

  • 没有找到相关文章

最新更新