Android 演示者执行改造调用后调用的测试方法
Android test method called after presenter executes retrofit call
我正在使用 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
}
我认为一种可能的解决方案是在每次调用 getAllResults
时模拟 ResultsDataService
调用任何回调的 onResponse
方法。
不幸的是,您在 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
成为一个接口,这样您的演示者不依赖于具体的实现,而只依赖于接口。这样就灵活多了。
希望这对您有所帮助。请记住,这是执行此操作的一种方法,不是单一方法。
我正在使用 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
}
我认为一种可能的解决方案是在每次调用 getAllResults
时模拟 ResultsDataService
调用任何回调的 onResponse
方法。
不幸的是,您在 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
成为一个接口,这样您的演示者不依赖于具体的实现,而只依赖于接口。这样就灵活多了。
希望这对您有所帮助。请记住,这是执行此操作的一种方法,不是单一方法。