【发布时间】:2017-08-10 11:28:00
【问题描述】:
我正在使用 Mockito 来测试 Presenter 功能。我已经构建了一些 Fake 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();
}
【问题讨论】:
-
您是否在测试设置中使用任何操作来将调度程序更改为即时?如果不是,则可能是线程问题。
-
@Jahnold 我认为这就是问题所在;
.observeOn可能会切换调度程序,并且测试线程不会等待。 -
@TassosBassoukos 在我的版本中,在 SetUp 中,我将 MainThreadScheduler 设置为 Inmediate。如果问题仍然是.observeOn,我怎样才能让测试线程等待观察者?
-
好的,测试肯定不会等待可观察的完成。我放了一个 Thread.sleep ,然后它就起作用了。但现在我想知道我该怎么做才能等待可观察对象完成而不是 Thread.sleep。我试图将“.toBlocking”放在“when”的可观察对象中,但编译器说“无法解析方法 thenReturn with BlockingObservable”)
标签: android unit-testing mockito rx-java retrofit2