如何告诉被测试对象使用模拟而不是自己的变量



我正在尝试测试LoginPresenter,并且我正在使用Mockito进行模拟。Mockito不允许我在SUT上verify方法调用,所以我必须模拟它的依赖项,并且verify他们的方法已被LoginPresenter调用。

我遇到了以下情况:

LoginPresenter有一个名为attemptLogin的方法:

private void attemptLogin(String username, String password) {
    new LoginNetworkOperation(username, password).execute();
}

我必须模拟LoginNetworkOperation并使用 Mockito,verify execute()的方法调用。

@Test
public void testWhenUserNameAndPasswordAreEnteredShouldAttemptLogin() throws Exception {
    LoginView loginView = Mockito.mock(LoginView.class);
    LoginNetworkOperation loginNetworkOperation = Mockito.mock(LoginNetworkOperation.class);
    Mockito.when(loginView.getUserName()).thenReturn("George");
    Mockito.when(loginView.getPassword()).thenReturn("aaaaaa");
    loginPresenter.setLoginView(loginView);
    loginPresenter.onLoginClicked();
    Mockito.verify(loginNetworkOperation.execute());
}

但是,如何使LoginPresenter使用模拟的登录网络操作,而不是它在attemptLogin方法中创建的操作?我需要更改 LoginPresenter 的设计以使用成员变量,并为其提供一个资源库,这是次优的,因为方法中的局部变量很多,因为它只在那里使用。

我把整件事做错了吗?

最初,我想验证是否调用了LoginPresenterattemptLogin,但 Mockito 只能验证模拟对象的方法,我无法监视LoginPresenter因为它是最终的(由 AndroidAnnotations 生成)

我在这个视频中找到了答案:https://www.youtube.com/watch?v=wEhu57pih5w

最大的收获是:不要将对象创建逻辑与业务逻辑混为一谈这意味着不要实例化方法或构造函数中的对象(可能改用 DI),因为每当调用 SUT 的构造函数或绑定到 new 关键字时,测试代码就无法控制链式反应启动。

这意味着在我的情况下,LoginPresenter不应该负责创建LoginNetworkOperation对象,而应该从外部获取它。

这样我就可以告诉它使用模拟而不是具体的实现,因此,我将能够进行测试

相关内容

  • 没有找到相关文章

最新更新