2016-01-23 78 views
3

我正嘗試將我的應用程序遷移到RxJava。 我已經使用Retrofit,因此我試圖使用Retrofit接口哪些方法返回Observables。 但是我現在遇到了編碼測試問題,因爲我無法使Observable在主線程上運行;我試圖爲它使用Scheduler.immediate()。 似乎Retrofit不允許重寫它的行爲,這對於真正的執行流程來說是完全有意義的,但它使測試變得非常困難。 因爲我剛剛開始使用RxJava + Retrofit,我只是希望我做錯了。是否有可能同步運行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); 
} 
+0

「改造不允許覆蓋它的行爲」 - 你能詳細說明嗎?沒有看到代碼很難說。 –

+0

@AononHe,似乎不可能在主線程上運行Retrofit Observable,比如我想使用Scheduler.immediate()爲我的測試執行操作。 – nyarlathotep77

回答

5

如果您修改測試以添加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(); 
} 

我擡頭的源代碼改造1.9.0和作爲每RxSupport類,該呼叫在由httpExecutor提供一個單獨的線程總是進行。因此,使用Schedulers.immediate()不會導致主線程中發生調用。

+0

謝謝您的詳細回答。那正是我正在做的,但是我的測試在實際的REST請求之前完成。實際上,在測試運行時,我看不到任何Retrofit日誌。 – nyarlathotep77

+0

我實際上可以看到Retrofit日誌,並且請求得到正確執行,但我仍然得到:'java.lang.AssertionError:Not completed!' – nyarlathotep77

+0

這會發生在你使用'subscribeOn(scheduler)'方法可以在您嘗試測試的方法中觀察到。這會導致測試和Retrofit在不同的線程上運行。您有兩種選擇:首先是注入調度程序,以便您可以用測試中的Schedulers.immediate()替換調度程序。如果你已經使用了'subscribeOn(Schedulers.io())',那麼你必須使用第二種使用RxJavaPlugins和RxJavaSchedulersHook的方法。 –

相關問題