2017-10-09 4 views
0

TestScheduler을 사용하기 시작했습니다. 나는이 대신 사용하는 경우일반용 TestScheduler RxJava로 관찰 가능

@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.interval과 함께 TestScheduler을 사용하고 첫 번째 예제에서와 같이 스케줄러를 출고시 방법으로 전달합니다. 이 방법을 사용할 수없는 이유는 실제 앱에서 관찰 가능 항목이 이처럼 단순하지 않고 스케줄러를 통과 할 수 없기 때문입니다. 두 번째 예제에서 수행하는 것처럼 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()); 
} 

편집

차이가 없음을 나는

@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() 문서를보십시오. 그러면 해당 간격에 기본 스케줄러가 사용됩니다. 기본 스케줄러는 계산입니다. subscriber가 호출되지 않으면 다른 스케줄러를 사용했을 수 있습니다. 그래서 당신은 JUnit-Runner-Thread를 막을 필요가 있습니다. 그 방법은 JVM을 빠져 나와 JVM을 중단하지 않을 것입니다. –

+0

나는 test2에 대한 예제를 추가했다. –