如何告诉被测对象使用模拟而不是它自己的变量
How to tell the subject under test to use the mock instead of its own variable
我正在尝试测试 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
's attemptLogin
is called, but Mockito can only verify mocked objects' 方法,但我无法监视 LoginPresenter
,因为它是最终的(由 AndroidAnnotations
生成)
我在这个视频中找到了答案:
https://www.youtube.com/watch?v=wEhu57pih5w
最大的收获是:不要将对象创建逻辑与业务逻辑混合
这意味着不要在方法或构造函数中实例化对象(可能改用 DI),因为测试代码无权控制每当 SUT 的构造函数或方法被调用时链式反应开始,即绑定到 new
关键字。
这意味着在我的例子中,LoginPresenter
不应该负责创建 LoginNetworkOperation
对象,而应该从外部获取它
这样我就可以告诉它使用模拟而不是具体实现,这样我就可以进行测试
我正在尝试测试 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
's attemptLogin
is called, but Mockito can only verify mocked objects' 方法,但我无法监视 LoginPresenter
,因为它是最终的(由 AndroidAnnotations
生成)
我在这个视频中找到了答案: https://www.youtube.com/watch?v=wEhu57pih5w
最大的收获是:不要将对象创建逻辑与业务逻辑混合
这意味着不要在方法或构造函数中实例化对象(可能改用 DI),因为测试代码无权控制每当 SUT 的构造函数或方法被调用时链式反应开始,即绑定到 new
关键字。
这意味着在我的例子中,LoginPresenter
不应该负责创建 LoginNetworkOperation
对象,而应该从外部获取它
这样我就可以告诉它使用模拟而不是具体实现,这样我就可以进行测试