我正在尝试测试LoginPresenter
,我正在使用Mockito进行模拟。
Mockito不让我verify
在SUT上进行方法调用,所以我必须模拟它的依赖关系,而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
使用模拟的LoginNetworkOperation而不是它在attemptLogin
方法中创建的那个?我需要更改LoginPresenter的设计以使用成员变量,并为它提供一个setter,这是次优的,因为方法中的局部变量很多,因为它只在那里使用。
我是否认为这件事错了?
最初,我想确认调用了LoginPresenter
的{{1}},但Mockito只能验证模拟对象的方法,我无法监视attemptLogin
,因为它是最终的(生成) LoginPresenter
)
答案 0 :(得分:1)
我在这段视频中找到了答案: https://www.youtube.com/watch?v=wEhu57pih5w
最大的好处是:不要将对象创建逻辑与业务逻辑混合 这意味着不要在方法或构造函数中实例化对象(可能使用DI代替),因为只要调用SUT的构造函数或方法,测试代码就无法启动链式反应,它绑定到{{1} } keyword。
这意味着在我的情况下,new
不应该负责创建LoginPresenter
对象,而应该从外部获取
这样我就可以告诉它使用mock而不是具体的实现,因此,我将能够进行测试