我正在使用Mockito测试Presenter功能。我已经构建了一些假的API响应,并且我已经成功测试了它们。
但是当我想从Observable调用OnError时,它不会被调用。
我在名为ApiCalls.java的类中使用此函数:
public Observable<List<Person>> getPeople(String location)
{
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
APIService service = retrofit.create(APIService .class);
return service.getPeople(location);
}
Presenter中的功能如下:
public void getPeople(final String location) {
Observable observable= apiCalls.getPeople(location);
observableResult.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<List<Person>>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
Log.w("ON ERROR",e.getMessage());
view.showError("An error has occurred");
}
@Override
public void onNext(List<Person> people) {
view.refreshPeople(people);
}
});
}
然后,在单元测试中,我尝试这样做:
when(apiCalls.getPeople("London"))
.thenReturn(Observable.error(new HttpException(buildResponse())));
presenter.getPeople("London");
verify(peopleView).showError(Mockito.anyString());
buildResponse:
public Response buildResponse()
{
String json = getJSONError();
Response response = Response.error(403, ResponseBody.create(MediaType.parse("application/json") ,json));
return response;
}
但是,当我测试时,会出现以下消息错误:
Wanted but not invoked:
peopleView.showError(<any string>);
-> at com.lordwater.myapp.PeoplePresenterImpl.testError(PeoplePresenterTest.java:154)
编辑:在设置中,我将调度程序设置为中级:
@Before
public void setUp() {
RxAndroidPlugins.getInstance().registerSchedulersHook(new RxAndroidSchedulersHook() {
@Override
public Scheduler getMainThreadScheduler() {
return Schedulers.immediate();
}
});
presenter = new PeoplePresenterImpl(peopleView);
}
@After
public void tearDown() {
RxAndroidPlugins.getInstance().reset();
}
答案 0 :(得分:3)
您的案例中的问题是您没有覆盖Schdeulers.io()
挂钩中的RxJavaPlugins
,而只是覆盖mainThread Scheduler:
@Override
public Scheduler getIOScheduler() {
return Schedulers.immediate();
}
正如您所说,在测试真正的异步调用时,您必须等待结果,否则测试将最终没有结果,但网络操作本身仍然发生在单独的线程上,因此不会阻塞测试线程,并且测试没有结果。
关于toBlocking()
,toBlocking()
在您想观察结果/ {onNext()
)时非常有用,这会将您的Obesrvable
转换为BlockingObservable
有点类似于内存集合,这意味着你需要调用:
apiCalls.getPeople("London")
.toBlocking()
.first();
会阻止直到有答案,然后你可以assertEquals
这个结果
但是您的方案在此处有所不同,您希望验证订阅者是否按预期使用onError()
,这意味着您还在测试订阅。