演示者执行改造调用后调用的 Android 测试方法



我正在使用 Mockito 来测试我的观点,但我的测试失败了,因为应该在改造调用完成后调用的方法。如何模拟演示者在完成改造调用后调用其方法的视图?我想验证是否已调用下面的unBlockUI()。我的测试显示blockUI()被调用,但unblockUI()没有被调用。

我收到失败消息

Wanted but not invoked:
view.unBlockUI();

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

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每次调用任何回调时调用getAllResultsonResponse方法。

不幸的是,您在fetchResults中创建ResultsDataService的方式使得很难做到这一点。这就是我们所说的紧密耦合。你有一个严格依赖于ResultsDataService的方法,没有机会改变它。因此,您无法从外部控制演示者。根据经验,每次您看到new运算符时,都是紧密耦合的迹象。

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

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

这可能看起来不多,但现在在测试中,您可以传递配置的模拟,而在您的应用程序中,您只需通过实际服务即可。

现在在你的测试中,你会配置一个模拟,如下所示:

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

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

请注意,您可以执行类似操作来测试onFailure。您还应该ResultsDataService一个接口,这样您的演示器就不依赖于具体的实现,而只是依赖于接口。这要灵活得多。

希望这有帮助。请记住,这是一种方法,而不是单一方法。

相关内容

  • 没有找到相关文章

最新更新