是否可以同步 运行 一个 Retrofit observable?
Is it possible to run a Retrofit observable synchronously?
我正在尝试迁移我的应用程序以使用 RxJava。
我已经在使用 Retrofit,因此我正在尝试使用方法 return Observables 的 Retrofit 接口。
但是,我现在在针对它进行编码测试时遇到问题,因为我无法在主线程上将 Observable 设置为 运行;我正在尝试为此使用 Scheduler.immediate() 。
似乎 Retrofit 不允许覆盖它的行为,这对实际执行流程来说完全有意义,但它使测试变得非常困难。
因为我刚刚开始使用 RxJava + Retrofit,所以我希望我做错了什么。
代码如下所示:
@Test
public void shouldCompleteRequest() {
SomeRestRequest request = new SomeRestRequest(arg1, arg2);
TestSubscriber<SomeRestResponse> testSubscriber = new TestSubscriber<>();
new SomeRestCommand(mRestApi,
arg1, arg2
Schedulers.immediate(),
Schedulers.immediate(),
mMockEventBus).execute(request, testSubscriber);
testSubscriber.assertCompleted();
}
其中
public void execute(T request, Observer<S> observer) {
getCommand(request)
.observeOn(mObserveOnScheduler) //The test injects Schedulers.immediate()
.subscribeOn(mSubscribeOnScheduler) //The test injects Schedulers.immediate()
.subscribe(observer);
}
,
@Override
protected Observable<SomeRestResponse> getCommand(SomeRestRequest request) {
return mRestApi.restCommand(arg1, arg2);
}
和
public interface RestApi {
@GET("/someEndPoint")
Observable<SomeRestResponse> restCommand(@Query("arg1") String arg1, @Query("arg2") String arg2);
}
如果您修改测试以添加 testSubscriber.awaitTerminalEvent();
,那么您的测试将等待调用完成,因此测试将通过。您仍然需要执行 assertCompleted()
,因为终端事件可以是成功完成也可以是错误。
@Test
public void shouldCompleteRequest() {
SomeRestRequest request = new SomeRestRequest(arg1, arg2);
TestSubscriber<SomeRestResponse> testSubscriber = new TestSubscriber<>();
new SomeRestCommand(mRestApi,
arg1, arg2
Schedulers.immediate(),
Schedulers.immediate(),
mMockEventBus).execute(request, testSubscriber);
testSubscriber.awaitTerminalEvent(); // add this line here
testSubscriber.assertCompleted();
}
我查阅了 Retrofit 1.9.0 的源代码,根据 RxSupport
class,调用总是在 httpExecutor
提供的单独线程中执行。因此使用 Schedulers.immediate()
不会导致调用发生在主线程中。
我正在尝试迁移我的应用程序以使用 RxJava。 我已经在使用 Retrofit,因此我正在尝试使用方法 return Observables 的 Retrofit 接口。 但是,我现在在针对它进行编码测试时遇到问题,因为我无法在主线程上将 Observable 设置为 运行;我正在尝试为此使用 Scheduler.immediate() 。 似乎 Retrofit 不允许覆盖它的行为,这对实际执行流程来说完全有意义,但它使测试变得非常困难。 因为我刚刚开始使用 RxJava + Retrofit,所以我希望我做错了什么。
代码如下所示:
@Test
public void shouldCompleteRequest() {
SomeRestRequest request = new SomeRestRequest(arg1, arg2);
TestSubscriber<SomeRestResponse> testSubscriber = new TestSubscriber<>();
new SomeRestCommand(mRestApi,
arg1, arg2
Schedulers.immediate(),
Schedulers.immediate(),
mMockEventBus).execute(request, testSubscriber);
testSubscriber.assertCompleted();
}
其中
public void execute(T request, Observer<S> observer) {
getCommand(request)
.observeOn(mObserveOnScheduler) //The test injects Schedulers.immediate()
.subscribeOn(mSubscribeOnScheduler) //The test injects Schedulers.immediate()
.subscribe(observer);
}
,
@Override
protected Observable<SomeRestResponse> getCommand(SomeRestRequest request) {
return mRestApi.restCommand(arg1, arg2);
}
和
public interface RestApi {
@GET("/someEndPoint")
Observable<SomeRestResponse> restCommand(@Query("arg1") String arg1, @Query("arg2") String arg2);
}
如果您修改测试以添加 testSubscriber.awaitTerminalEvent();
,那么您的测试将等待调用完成,因此测试将通过。您仍然需要执行 assertCompleted()
,因为终端事件可以是成功完成也可以是错误。
@Test
public void shouldCompleteRequest() {
SomeRestRequest request = new SomeRestRequest(arg1, arg2);
TestSubscriber<SomeRestResponse> testSubscriber = new TestSubscriber<>();
new SomeRestCommand(mRestApi,
arg1, arg2
Schedulers.immediate(),
Schedulers.immediate(),
mMockEventBus).execute(request, testSubscriber);
testSubscriber.awaitTerminalEvent(); // add this line here
testSubscriber.assertCompleted();
}
我查阅了 Retrofit 1.9.0 的源代码,根据 RxSupport
class,调用总是在 httpExecutor
提供的单独线程中执行。因此使用 Schedulers.immediate()
不会导致调用发生在主线程中。