如何告诉被测对象使用模拟而不是其自己的变量 [英] How to tell the subject under test to use the mock instead of its own variable

查看:99
本文介绍了如何告诉被测对象使用模拟而不是其自己的变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试测试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和verifyexecute()上的方法调用.

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?

最初,我想验证是否调用了LoginPresenterattemptLogin,但是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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆