如何告诉被测对象使用模拟而不是其自己的变量 [英] How to tell the subject under test to use the mock instead of its own variable
问题描述
我正在尝试测试LoginPresenter
,并且我正在使用Mockito进行模拟.
Mockito不允许我verify
在SUT上进行方法调用,因此我必须模拟其依赖项,并且verify
他们的方法已由LoginPresenter
调用.
I am trying to test a LoginPresenter
, and I am using Mockito for the mocks.
Mockito doesnt let me verify
a method invocation on the SUT so I have to mock its dependencies and verify
their methods have been called by the LoginPresenter
.
我遇到以下情况:
LoginPresenter有一个名为attemptLogin
的方法:
LoginPresenter has a method called attemptLogin
:
private void attemptLogin(String username, String password) {
new LoginNetworkOperation(username, password).execute();
}
我必须模拟LoginNetworkOperation
并使用Mockito和verify
在execute()
上的方法调用.
I have to mock LoginNetworkOperation
and using Mockito, verify
the method invocation on 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,这是次优的,因为该方法中的局部变量很多,因为该变量仅在其中使用.
However, how do I make LoginPresenter
use the mocked LoginNetworkOperation instead of the one it creates in the attemptLogin
method? I need to change the design of LoginPresenter to use a member variable, and provide a setter for it, which is suboptimal because a local variable in the method is plenty, as it is used only there.
我要把这整个事情弄错了吗?
Am I going about this whole thing wrong?
最初,我想验证是否调用了LoginPresenter
的attemptLogin
,但是Mockito只能验证模拟对象的方法,并且我无法监视LoginPresenter
,因为它是最终的(由AndroidAnnotations
生成)
Initially, I wanted to verify that LoginPresenter
's attemptLogin
is called, but Mockito can only verify mocked objects' methods and I cannot spy on LoginPresenter
because it is final (generated by AndroidAnnotations
)
推荐答案
我在此视频中找到了答案: https://www.youtube.com/watch?v=wEhu57pih5w
I found the answer in this video: https://www.youtube.com/watch?v=wEhu57pih5w
最大的收获是:不要将对象创建逻辑与业务逻辑混在一起
这意味着不要实例化方法或构造函数中的对象(可能改用DI),因为无论何时调用SUT的构造函数或方法(绑定到new
关键字),测试代码都无法控制链式反应的开始时间
The biggest takeaway is: don't mix object creation logic with business logic
which means don't instantiate objects in methods or constructors (probably use DI instead), because the test code has no power over what chain-reaction starts whenever a SUT's constructor or a method is called, that is bound to a new
keyword.
这意味着在我的情况下,LoginPresenter
不应该负责创建LoginNetworkOperation
对象,而应该从外部获取它
That means that in my case, the LoginPresenter
shouldn't be responsible for creating the LoginNetworkOperation
object but should take it from the outside
这样,我将能够告诉它使用模拟而不是具体的实现,因此,我将能够进行测试
That way I will be able to tell it to use the mock instead of the concrete implementation, and thus, I will be able to do my tests
这篇关于如何告诉被测对象使用模拟而不是其自己的变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!