2017-10-12 14 views
0

私はRxバッファに何かをキャッシュし、ある程度の間隔(10秒)後にこのテスト対象のバッファに値を挿入するかどうかを調べますルームデータベース。Kotlin:Thread.sleepを使用するテストをRxJavaに変換する方法TestScheduler

Thread.sleep(syncTimeInterval)を使用すると、テストは正しく行われます。私はこの同じテストをTestSchedulerを使用して記述したいと思います。

ここで、それはのThread.sleep版(試験に合格する)である:

@Test 
fun testMultipleLogs() { 
    val loadAllCloudCallBefore = appDatabase.logCloudCallDao().loadAll() 
    val loadAllLogNewSessionBefore = appDatabase.logNewSessionDao().loadAll() 

    assertEquals(0, loadAllCloudCallBefore.size) 
    assertEquals(0, loadAllLogNewSessionBefore.size) 


    Observable.interval(1, TimeUnit.SECONDS) 
      .take(20) 
      .subscribe { logManager.logNewSession() } 

    Observable.interval(1, TimeUnit.SECONDS) 
      .take(20) 
      .subscribe { logManager.logCloudCall("url", "callgoup") } 

    Observable.interval(1, TimeUnit.SECONDS) 
      .take(20) 
      .subscribe { logManager.logNewSession() } 

    Observable.interval(1, TimeUnit.SECONDS) 
      .take(20) 
      .subscribe { logManager.logCloudCall("url", "callgoup") } 

    Observable.interval(1, TimeUnit.SECONDS) 
      .take(20) 
      .subscribe { logManager.logNewSession() } 

    Observable.interval(1, TimeUnit.SECONDS) 
      .take(20) 
      .subscribe { logManager.logCloudCall("url", "callgoup") } 


    Thread.sleep(30000) 

    val loadAllCloudCallAfter = appDatabase.logCloudCallDao().loadAll() 
    val loadAllLogNewSessionAfter = appDatabase.logNewSessionDao().loadAll() 

    assertEquals(60, loadAllCloudCallAfter.size) 
    assertEquals(60, loadAllLogNewSessionAfter.size) 
} 

そして、ここでは、このテストは合格ではない、TestSchedulerだけ進めた時間を期待して後のサイズは0(ない60)

です
@Test 
fun testMultipleLogs() { 
    var testScheduler: TestScheduler = TestScheduler() 

    val loadAllCloudCallBefore = appDatabase.logCloudCallDao().loadAll() 
    val loadAllLogNewSessionBefore = appDatabase.logNewSessionDao().loadAll() 

    assertEquals(0, loadAllCloudCallBefore.size) 
    assertEquals(0, loadAllLogNewSessionBefore.size) 


    Observable.interval(1, TimeUnit.SECONDS, testScheduler) 
      .take(20) 
      .subscribe { logManager.logNewSession() } 

    Observable.interval(1, TimeUnit.SECONDS, testScheduler) 
      .take(20) 
      .subscribe { logManager.logCloudCall("url", "callgoup") } 

    Observable.interval(1, TimeUnit.SECONDS, testScheduler) 
      .take(20) 
      .subscribe { logManager.logNewSession() } 

    Observable.interval(1, TimeUnit.SECONDS, testScheduler) 
      .take(20) 
      .subscribe { logManager.logCloudCall("url", "callgoup") } 

    Observable.interval(1, TimeUnit.SECONDS, testScheduler) 
      .take(20) 
      .subscribe { logManager.logNewSession() } 

    Observable.interval(1, TimeUnit.SECONDS, testScheduler) 
      .take(20) 
      .subscribe { logManager.logCloudCall("url", "callgoup") } 


    testScheduler.advanceTimeBy(21, TimeUnit.SECONDS) 

    val loadAllCloudCallAfter = appDatabase.logCloudCallDao().loadAll() 
    val loadAllLogNewSessionAfter = appDatabase.logNewSessionDao().loadAll() 

    assertEquals(60, loadAllCloudCallAfter.size) 
    assertEquals(60, loadAllLogNewSessionAfter.size) 
} 

このケースを正しくテストするにはどうすればよいですか?方法はありますか?

fun logCloudCall(url: String, callGroup: String) { 
    val logCloudCall = LogCloudCall(url = url, callGroup = callGroup, date = Converter.GENERAL_DATE_FORMAT.format(Date())) 

    Log.v("LogManager", logCloudCall.toString()) 
    addLog(logCloudCall) 
} 

    fun logNewSession() { 
    val logNewSession = 
      LogNewSession(
        date = Converter.GENERAL_DATE_FORMAT.format(Date())) 
    Log.v("LogManager", logNewSession.toString()) 

    addLog(logNewSession) 
} 

    fun addLog(logEvent: LogEvent) { 
    source.onNext(logEvent) 
} 

そして、これは私が私のLogManagerのinitに使用するメカニズムです::

val source = PublishSubject.create<LogEvent>().toSerialized() 

var logRepository: LogRepository 

init { 
    logRepository = LogRepositoryImpl(context) 
    configureSubject() 
} 


fun configureSubject() { 
    source 
      .buffer(10, TimeUnit.SECONDS) 
      .subscribe { bufferedData -> proceedValues(bufferedData) } 
} 

答えて

0

次のテストパスLogManagerの中

関数は次のようになります

UPDATE :

@Test 
fun foo() { 
    val testScheduler = TestScheduler() 
    var count = 0 

    Observable.interval(1, TimeUnit.SECONDS, testScheduler) 
      .take(20) 
      .subscribe { count++ } 

    testScheduler.advanceTimeBy(21, SECONDS) 

    assert(count == 20) 
} 

つまり、テストコードは正しく表示されますが、結果は正しくありません。ここで唯一不明なのはlogManagerコードです。そのクラスにスレッドがありますか?それはカウントがまだ0である理由を説明するかもしれません:あなたは競合状態があるかもしれません。


それはおそらくbufferコールによるものです。

public final Observable<List<T>> buffer(long timespan, TimeUnit unit) { 
    return buffer(timespan, unit, Schedulers.computation(), Integer.MAX_VALUE); 
} 

これはおそらく、あなたが見ているスレッドの問題になります:bufferは内部で計算Schedulerを使用しています。

+0

私の質問が更新されました。はい、確実にスレッドがあります。私はちょうど時間の後に私のDBにバッファリングされたオブジェクトを保存しています – Konrad

+0

@okset私の変更を参照してください – nhaarman

+0

ありがとう、しかし、これを管理する方法がまだわからない、私はちょうど私の仕事をテストするより便利な方法を使用したいコード(最初の方法でテストしたところで動作します) – Konrad

関連する問題