【问题标题】:Mock final method in inner class with PowerMockito使用 PowerMockito 在内部类中模拟最终方法
【发布时间】:2018-01-03 18:34:43
【问题描述】:

我在存根 final 方法时遇到问题,该方法在我要测试的类中使用。我的测试类中有问题的行在这里:

PowerMockito.when(connectionMock.authUser("fake-user", "fake-password")).thenReturn("random string");

抛出 NullPointerException。我的测试类如下所示:

@RunWith(PowerMockRunner.class)
@PrepareForTest({MyClass.class, APIClientConnection.class})
public class MyClassTest {
    @Test
    public void apiConnect() throws Exception {
        MyClass c = new MyClass();
        APIClientConnection connectionMock = PowerMockito.mock(APIClientConnection.class);
        PowerMockito.whenNew(APIClientConnection.class).withAnyArguments().thenReturn(connectionMock);
        PowerMockito.when(connectionMock.authUser("fake-user", "fake-password")).thenReturn("random string");
        c.apiConnect("fake-host", 80, "fake-user", "fake-password");
    }
}

我正在测试的类如下:

public class MyClass {
    public MyClass() { }
    public APIClientConnection apiConnect(String host, int port, String user, String pass) {
            conn = new APIClientConnection(host, port);
            conn.authUser(user, pass);
    }
}

其中 authUser() 的最终定义如下:

public class APIClientConnection {
    public final String authUser(String username, String password) {
        ...
    }
}

我正在关注 How to mock non static methods using PowerMockCan Powermockito mock final method in non-final concrete class?。我尝试了一些变体,例如使用 Mockito 而不是 PowerMock 来存根 authUser,并将 APIClientConnection.class 添加到 PrepareForTest 注释中。我不知道为什么它不起作用。我做错了什么?

【问题讨论】:

    标签: java unit-testing mockito powermock powermockito


    【解决方案1】:

    你的问题来了

    PowerMockito.when(connectionMock.authUser("user", "password")).thenReturn("random string");
    c.apiConnect("fake-host", 80, "fake-user", "fake-password");
    

    当用户使用凭据user/password 登录时,您指出该方法应该被存根,但您发送的是fake-user/fake-password

    将最后一行替换为 c.apiConnect("fake-host", 80, "user", "password");

    【讨论】:

    • Ack,抱歉 - 我正在清理代码,而忽略了修复存根方法中的参数。匹配它们,甚至使用任何字符串匹配器,例如PowerMockito.when(conn.authUser(anyString(), anyString())).thenReturn("random string");,仍然会产生 NullPointerException。
    • 你的方法apiConnect没有返回语句。请发布整个代码
    【解决方案2】:

    操作员错误:X

    由于我在发布之前对代码进行了清理,因此出现了两个错别字。在上面用户指出的错误中,stub中的参数,和传递给实际方法调用的参数不匹配。这不是我的问题,因为我在帖子中键入时引入了错字,并且没有反映在我正在运行的代码中。

    第二个错字实际上导致了我的问题。我的实际代码正在使用:

    APIClientConnection conn = Mockito.mock(APIClientConnection.class);
    

    我以某种方式设法在我的帖子中变成了这个:

    APIClientConnection conn = PowerMockito.mock(APIClientConnection.class);
    

    在我的代码中将“Mockito.mock”切换为“PowerMockito.mock”后,它就开始工作了。因此,不知何故,我在发布自己的问题时设法引入了修复程序。 :/

    向一直盯着这个想知道发生了什么的人表示诚挚的歉意!我想我已经盯着它太久了。上面的代码应该可以工作,也许它会对某人有所帮助。

    【讨论】:

    • 也许@PrepareForTest 在问题中也不完整?例如:@PrepareForTest(MyClass.class) 而不是 @PrepareForTest({MyClass.class, APIClientConnection.class})
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多