模拟改造 可观察到的错误



我正在使用Mockito来测试演示器函数。我已经构建了一些虚假的 API 响应,并且已经成功测试了它们。

但是当我想从可观察量调用 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);
}

演示器中的函数如下:

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());

和构建响应:

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();
}

在你的例子中,问题是你没有在RxJavaPlugins钩子中覆盖Schdeulers.io(),而只是主线程调度程序:

@Override
public Scheduler getIOScheduler() {
    return Schedulers.immediate();
}

正如您所说,在测试真正的异步调用时,您必须等待结果,否则测试最终将没有结果,但网络操作本身仍然发生在单独的线程上,因此不会阻塞测试线程,并且测试完成没有结果。

关于toBlocking(),当您想观察结果(onNext()(时,toBlocking()很有用,这会将您的Obesrvable转换为BlockingObservable,其作用与内存收集有点相似,这意味着您需要调用:

 apiCalls.getPeople("London")
    .toBlocking()
    .first();

这将阻止,直到有答案,然后你可以assertEquals这个结果。
但你的方案在这里有所不同,你想要验证订阅者是否按预期onError() 运行,这意味着你也在测试订阅。

相关内容

  • 没有找到相关文章

最新更新