首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用Powermock的Whitebox.invokeMethod(对象实例、对象...当我的第一个方法参数是字符串类型时?

如何使用Powermock的Whitebox.invokeMethod(对象实例、对象...当我的第一个方法参数是字符串类型时?
EN

Stack Overflow用户
提问于 2015-09-25 02:28:18
回答 1查看 25.4K关注 0票数 1

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

代码语言:javascript
复制
invokeMethod(Object instance, Object... arguments)

我遇到的问题是我的第一个参数是String类型。这将调用带有签名的invokeMethod()

代码语言:javascript
复制
invokeMethod(Object instance, String methodToExecute, Object... arguments)

这是一个测试的模型。

代码语言:javascript
复制
@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);
}

这给了我一个错误,

代码语言:javascript
复制
org.powermock.reflect.exceptions.MethodNotFoundException: No method found with name '123A48' with parameter types: [ AnEnum ] in class TheClassBeingTested.`

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

代码语言:javascript
复制
@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);
}

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

EN

回答 1

Stack Overflow用户

发布于 2015-09-25 04:04:48

您真正需要做的是查看TheClassBeingTested.java。错误消息告诉您,问题是Whitebox.invoke方法在它通过反射创建的TheClassBeingTested中找不到名为"123A48“的方法。在本例中,我认为您选择的invokeMethod是查找参数(Object classUnderTest、String methodName、Object...parameters)。

尝试如下所示:

代码语言:javascript
复制
public class TheClassBeingTested {
    private String foo;

    public void setFoo(String fooValue) {
        foo = fooValue;
    }

    public String getFoo() {
        return foo;
    }

}

然后,您可以像这样使用白盒进行测试:

代码语言:javascript
复制
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);
     }
}

希望这能有所帮助。

..。下面已编辑的回复

由于我在从事其他开发工作时没有仔细阅读您的问题,所以我没有抓住要点。

在这种情况下,我将对您的测试进行以下修改,以避免调用方法不明确的问题:

代码语言:javascript
复制
@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(对象实例,对象...参数)将只看到对象数组,这是方法签名告诉编译器所期望的。尽管String是一个对象,但在方法签名反射中,java.lang.reflect遵循您认为您试图告诉它使用的第二个签名,而不是您希望它使用的签名。

希望这个答案能更好地满足你的要求。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32768430

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档