2016-10-26 3 views
3

リアクティブインタフェースを使用するDAOオブジェクトのテストを作成しようとしています。レシピを含むテーブルがあり、このテーブルにデータを挿入すると、サブスクライバはレシピを含むリストを受け取ることをテストしたい。ユニットテスト中のRxJava Schedulers.immediate()の動作

私はTestSubscriberクラスを使用しており、そのクラスに対してアサーションを実行しています。

@Test 
fun testSubscriber() { 
    insertItem() 
    val testSubscriber = TestSubscriber.create<List<Recipe>>() 

    recipeDao 
      .getRecipes() 
      .subscribeOn(Schedulers.immediate()) 
      .subscribe(testSubscriber) 

    testSubscriber.assertNoErrors() 
    testSubscriber.assertNoTerminalEvent() 
    testSubscriber.assertNotCompleted() 
    testSubscriber.assertValueCount(1) 
    assertEquals(1, testSubscriber.onNextEvents[0].size) 
} 

問題は項目が放出されなかったため、アサーションtestSubscriber.assertValueCount(1)が失敗したということである。このような私の簡単なテストを見て。しかし、この行を testSubscriber.awaitTerminalEvent(500, TimeUnit.MILLISECONDS)の上に挿入すると、テストは成功します。私の観測はターミナルイベントを出さないので、タイムアウトが実行されますが、待っている間はonNextはレシピのリストとともに呼び出されました。

マイgetRecipes方法:

fun getRecipes(): Observable<List<Recipe>> { 
    return query(SELECT("*") 
      .FROM(Recipe.TABLE_NAME) 
      .ORDER_BY(Recipe.COL_NAME)) 
      .run() 
      .mapToList(RecipeMapper.MAPPER) 
} 

どうということは可能ですか?私はSchedulers.immediate()を使用すると、同じスレッドで操作が実行され、TestSubscriberがイベントを受け取ると思っていました。もしそうでなければ、このテストをどのようにして成功させるべきですか?私はonNextが呼び出されていることをテストしたいと思っていますし、その間に人工のスリープコマンドを挿入したくありません。

+0

( 'delay'、' timer'、 'interval'などのように)あなたの' getRecipes'に時間依存の操作があると仮定したり、異なるSchedulerで 'observeOn'または' subscribeOn'を使用するとします。このような場合、テストのスケジューラは適用されません。レシピダオを見せていただけますか? –

+0

こんにちは、私は質問を編集し、私のgetRecipesメソッドを追加しました。私はサブスクリプションまたは観測スケジューラを変更していません。私は時間に敏感な操作をしていません。 – Billda

+0

'run()'メソッドは私には疑わしいと思われます - 'Observable'を返しますか?または 'mapToList'は' Observable'を返しますか?もしそうなら、おそらくそれらのメソッドの1つが独自のSchedulerを宣言していますか? –

答えて

3

問題は、ライブラリSqlBriteを追加のフレームワークSqlBrite-Daoとともに使用していたことでした。 SqlBriteは特定のスケジューラのクエリを監視しており、SqlBrite-DaoのDaoManagerに何も提供されていないときはSchedulers.io()が使用されていました。解決方法は、スケジューラをDaoManager.Builderに提供するか、またはRxJavaPluginsを適用し、すべてのSchedulerとしてSchedulers.immediate()を返すことです。

関連する問題