2017-10-09 13 views
0

私はTestSchedulerを使い始めました。私は、この代わりに使用する場合RxJavaで一般的なObservableのTestScheduler

@Test 
public void test1() throws Exception { 
    //when 
    TestScheduler scheduler = new TestScheduler(); 
    TestObserver<Long> subscriber = new TestObserver<>(); 

    //run 
    Observable 
      .interval(1L, TimeUnit.SECONDS, scheduler) 
      .subscribeWith(subscriber); 

    //check 
    scheduler.advanceTimeBy(200, TimeUnit.SECONDS); 
    assertEquals(200, subscriber.valueCount()); 
} 

:加入者が呼び出されることはありませんので

@Test 
public void test2() throws Exception { 
    //when 
    TestScheduler scheduler = new TestScheduler(); 
    TestObserver<Long> subscriber = new TestObserver<>(); 

    //run 
    Observable 
      .interval(1L, TimeUnit.SECONDS) 
      .observeOn(scheduler) 
      .subscribeOn(scheduler) 
      .subscribeWith(subscriber); 

    //check 
    scheduler.advanceTimeBy(200, TimeUnit.SECONDS); 
    assertEquals(200, subscriber.valueCount()); 
} 

テストが失敗したすべてが、このようなもので正常に動作します。

私が見つけたすべての例では、Observable.intervalTestSchedulerを使用して、最初の例のようにスケジューラをファクトリメソッドに渡します。 私はこのメソッドを使用できない理由は、実際のアプリケーションではobservablesはこのように単純ではなく、私はスケジューラに合格できないということです。 私は2番目の例でそれをやっているようにSchedulerを設定すると良いと思っていましたが、そうではないようです。

より一般的なObservablesにTestSchedulerを使用する正しい方法は何ですか?

TestSchedulerを使用せずに私は正常にこれらのメソッドを使用することができます。

@Test 
public void test3() throws Exception { 
    //when 
    Scheduler trampoline = Schedulers.trampoline(); 

    //run 
    TestObserver<Long> test = Observable 
      .interval(1L, TimeUnit.SECONDS) 
      .observeOn(trampoline) 
      .subscribeOn(trampoline) 
      .test(); 

    //check 
    test.await(3100,TimeUnit.MILLISECONDS); 
    assertEquals(3, test.valueCount()); 
} 

@Test 
public void test4() throws Exception { 
    //when 
    Scheduler trampoline = Schedulers.trampoline(); 

    //run 
    TestObserver<Long> test = Observable 
      .fromArray(1L, 2L, 3L) 
      .subscribeOn(trampoline) 
      .observeOn(trampoline) 
      .test(); 

    //check 
    assertEquals(3, test.valueCount()); 
} 

@Test 
public void test5() throws Exception { 
    //when 
    Scheduler trampoline = Schedulers.trampoline(); 

    //run 
    TestObserver<Long> test = Observable 
      .fromArray(1L, 2L, 3L) 
      .subscribeOn(trampoline) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .test(); 

    //check 
    test.awaitTerminalEvent(); 
    assertEquals(3, test.valueCount()); 
} 

EDIT

違いはありませんが、私は

@BeforeClass 
public static void setupClass() { 
    mScheduler = new TestScheduler(); 

    RxAndroidPlugins.setInitMainThreadSchedulerHandler(__ -> mScheduler); 
    RxJavaPlugins.setIoSchedulerHandler(__ -> mScheduler); 
} 

@Test 
public void test2() throws Exception { 
    //when 
    TestObserver<Long> subscriber = new TestObserver<>(); 

    //run 
    Observable 
      .interval(1L, TimeUnit.SECONDS) 
      .observeOn(mScheduler) 
      .subscribeOn(mScheduler) 
      .subscribeWith(subscriber); 

    //check 
    mScheduler.advanceTimeBy(200, TimeUnit.SECONDS); 
    assertEquals(200, subscriber.valueCount()); 
} 

答えて

1

を使用する場合は、標準のスケジューラを上書きしたい場合(間隔のために)使用することができます。他の標準スケジューラーを上書きすることもできます。

RxJavaPlugins.setComputationSchedulerHandler(scheduler -> testScheduler); 

testSchedulerはあなたのTestSchedulerだろう。プラグインを設定した後、あなたはtest1の

例のようにadvanceTimeを使用することができます。私は、演算スケジューラを使用していないので、これは最初にすべての作業することはできません

@Test 
// fails because interval schedules on different thread then JUnit-Runner-thread -> fall through 
void notWorkingTest1() throws Exception { 
    TestScheduler scheduler = new TestScheduler(); 
    TestObserver<Long> subscriber = new TestObserver<>(); 

    Observable 
      .interval(1L, TimeUnit.SECONDS) 
      .observeOn(scheduler) 
      .subscribeOn(scheduler) 
      .subscribeWith(subscriber); 

    //check 
    scheduler.advanceTimeBy(200, TimeUnit.SECONDS); 
    assertEquals(200, subscriber.valueCount()); 
} 


@Test 
// not working because interval will not be scheduled on virtual time -> JUnit-Runner-Thread will close because test observable emits on different thread 
void notWorkingTest2() throws Exception { 
    //when 
    TestScheduler scheduler = new TestScheduler(); 

    //run 
    TestObserver<Long> test = Observable 
      .interval(1L, TimeUnit.SECONDS) 
      .observeOn(scheduler) 
      .subscribeOn(scheduler) 
      .test(); 

    scheduler.advanceTimeBy(200, TimeUnit.SECONDS); 

    test.assertValueCount(200); 
} 

@Test 
// runs sync. -> no JUnit-Runner-thread blocking needed 
void workingTest() throws Exception { 
    TestScheduler scheduler = new TestScheduler(); 
    RxJavaPlugins.setComputationSchedulerHandler(s -> scheduler); 

    TestObserver<Long> test = Observable 
      .interval(1L, TimeUnit.SECONDS) // executed on Schedulers.computation() 
      .observeOn(scheduler) 
      .subscribeOn(scheduler) 
      .test(); 

    scheduler.advanceTimeBy(200, TimeUnit.SECONDS); 

    test.assertValueCount(200); 
} 
+0

。とにかく、他のスケジューラーをオーバーライドしても、結果は私がtest2で持っているものと同等です。私は私の質問を編集しました。 – user6405527

+0

interval()のドキュメントをご覧ください。そこには、その間隔がデフォルトスケジューラを使用して表示されます。デフォルトスケジューラは計算です。サブスクライバが呼び出されていない場合、別のスケジューラを使用している可能性があります。したがって、JUnit-Runner-Threadをブロックする必要があります.JUnit-Runner-Threadをブロックするだけで、JVMが機能しなくなり、JVMが終了することはありません。 –

+0

私はtest2のための例を加えました。これは働くプラスの説明です。 –

関連する問題