演示者执行改造调用后调用的Android测试方法 [英] Android test method called after presenter executes retrofit call

查看:95
本文介绍了演示者执行改造调用后调用的Android测试方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Mockito测试我的视图,但是由于应该在改造调用完成后调用该方法,因此测试失败。改造调用完成后,我该如何模拟演示者调用谁的方法?我想验证是否已调用下面的 unBlockUI()。我的测试显示,调用了 blockUI(),但未调用 unblockUI()

I'm using Mockito to test my views but my tests are failing because of a method that is supposed to be called after a retrofit call is complete. How can I mock a view who's method is called by presenter after completion of a retrofit call? I'd like to verify that unBlockUI() below has been called. My tests show blockUI() is called but unblockUI() is not being called.

我收到失败消息

Wanted but not invoked:
view.unBlockUI();

在我的演示者中,我有方法

In my presenter I have the method

public void fetchResults(){ 

    view.blockUI();

    ResultsDataService resultsDataService = new ResultsDataService()

    resultsDataService.getAllResults(new Callback<Catalog>() {

            @Override
            public void onResponse(Call<Catalog> call, Response<Catalog> response) {
                view.unBlockUI();

            }

            @Override
            public void onFailure(Call<Catalog> call, Throwable t) {
                view.unBlockUI();               
                t.printStackTrace();
            }
        })
}

结果数据服务。

public class ResultsDataService {

    private final RestApi restApi;

    public CatalogDataService() {
    //here I have a class that builds the REST Service
        restApi = RestServiceBuilder.createService(RestApi.class);
    }

    public void getAllResults() {
        Call<Catalog> call = restApi.getAllResults();
        call.enqueue(callback);
    }
}

我的测试方法

@Test
public void shouldFetchAllResults_allOK() {
presenter.fetchResults();`

verify(view).blockUI();//This is called
verify(view).unBlockUI();//this is not called
}


推荐答案

我认为一种可能的解决方案是模拟 ResultsDataService 调用<每次调用 getAllResults 时,任何回调的code> onResponse 方法。

I think one possible solution is to mock ResultsDataService to call the onResponse method of any callback every time getAllResults is called.

不幸的是,您在 fetchResults ResultsDataService 的方式$ c>使其很难执行。这就是我们所说的紧密耦合。您有一个严格依赖 ResultsDataService 的方法,没有机会对其进行更改。因此,您不能从外部控制演示者。根据经验,每次您看到 new 运算符时,都表示耦合紧密。

Unfortunately, the way you're creating your ResultsDataService inside fetchResults makes it really hard to do this. This is what we call tight coupling. You have a method that depends strictly on ResultsDataService with no chance to change it. Therefore you cannot control the presenter from the outside. As a rule of thumb, every time you see the new operator that's a sign of tight coupling.

通常使用依赖注入来解决这个问题。在代码中执行此操作的一种方法是,只需更改 fetchResults 方法以将服务作为参数接收:

Usually we use dependency injection to solve this. One way you can do it in your code is simply change the fetchResults method to receive the service as an argument:

public void fetchResults(@NonNull ResultsDataService service) {
   // ...
}

这似乎并不多,但是现在在测试中,您可以通过配置的模拟程序,而在应用程序中,您只需通过真实服务即可。

It might not seem much, but now in the test you can pass in a configured mock and in your app you just pass in the real service.

现在在测试中说,您将像这样配置模拟:

Say now in your test you'd configure a mock like so:

ResultDataService service = mock(ResultDataService.class);
doAnswer(new Answer() {
        @Override
        public Object answer(InvocationOnMock invocation) throws Throwable {
            Call call = (Call) invocation.getArgument(0);
            call.onResponse(call, <some response here>);
            return null;
        }
    }).when(service.getAllResults(any(Call.class)));    

您现在可以使用它将其传递给演示者 fetchResults

You can now use this to pass it to your presenter fetchResults.

上面的模拟物有什么作用?它将调用传入参数的 onResponse 方法。因此,基本上,当您调用 fetchResults 时,它将立即调用 onResponse 回调。在您的情况下,这将依次调用 unBlockUI

What does the mock above do? It will call the onResponse method of the passed in argument. So basically it will call right away the onResponse callback when you call fetchResults. In your case this will in turn call unBlockUI.

请注意,您可以执行类似的操作来测试 onFailure 。您还应该将 ResultsDataService 用作接口,因此您的演示者不依赖于具体的实现,而仅依赖于接口。

Notice you can do something similar to test the onFailure. You should also make ResultsDataService an interface, so your presenter doesn't depend on concrete implementations, but just interfaces. This is much more flexible.

希望这会有所帮助。请记住,这是一种执行此操作的方法,不是是一种方法。

Hope this helps. Remember, this is one way of doing this and not the single way.

这篇关于演示者执行改造调用后调用的Android测试方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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