2017-12-11 12 views
2

私は、通貨を一覧表示するシンプルなビューを持っています。アプリは1秒ごとにWebサービスから通貨を取得します。だから私は、私のViewModelにする方法を次ていますRxJava無限区間のテスト

fun onViewAppeared() { 
    currenciesViewStateUpdates.onNext(CurrenciesViewState(true, null)) 
    Flowable.interval(1, TimeUnit.SECONDS) 
    .flatMapSingle { _ -> currenciesService.calculateCurrencies(Currency("EUR", 10.0)) } 
    .doOnError { error -> Log.d("LOG", error.message) } 
    .observeOn(AndroidSchedulers.mainThread()) 
    .subscribe { currencies -> 
     currenciesViewStateUpdates.onNext(CurrenciesViewState(false, currencies)) 
    } 
} 

を今私は、この動作ユニットテストする必要があります。

@Test 
fun viewAppearedAndCurrenciesRequestSucceeded_currenciesDisplayed() { 
    val currencies = listOf(Currency("", 0.0)) 
    Mockito.`when`(currenciesServiceMock.calculateCurrencies(anyCurrency())).thenReturn(Single.just(currencies)) 
    viewModel.getViewStateUpdates().subscribe(testObserver) 

    viewModel.onViewAppeared() 

    testObserver.assertSubscribed() 
    testObserver.assertNoErrors() 
    testObserver.assertValueCount(2) 
    assertFalse(testObserver.values()[1].loading) 
    assertNotNull(testObserver.values()[1].currencies) 
    testObserver.values()[1].currencies?.let { assertTrue(it.isNotEmpty()) } 
} 

すべてRxSchedulersは即時のために設定します。問題:テストでは、観測可能なサブスクリプションが永遠に終わるのを待っていますが、無限の間隔で終了することはありません。どうすればテストできますか?

答えて

0

あなたが作成した方法でテストを実行する際に問題が発生します。

  1. スケジューラをテストおよび生産中に適切な方法で注入できるように、クラスパラメータにスケジューラを作成します。
  2. デッドロックが発生する可能性があるため、Schedulers.immediate()の代わりにテストスケジューラを使用してください。
  3. タイムアウトした操作(​​、timeout()など)は、明示的なスケジューラ(通常は注入したスケジューラ)で動作します。