Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/api/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unit testing 用RxJava实现通用可观测的TestScheduler_Unit Testing_Rx Java - Fatal编程技术网

Unit testing 用RxJava实现通用可观测的TestScheduler

Unit testing 用RxJava实现通用可观测的TestScheduler,unit-testing,rx-java,Unit Testing,Rx Java,我开始使用TestScheduler。使用这样的东西,一切都很好: @Test public void test1() throws Exception { //when TestScheduler scheduler = new TestScheduler(); TestObserver<Long> subscriber = new TestObserver<>(); //run 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());
}
编辑

如果我使用

@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());
}

如果要覆盖标准调度程序,可以将其用于间隔。也可以覆盖其他标准调度程序

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);
}

如果要覆盖标准调度程序,可以将其用于间隔。也可以覆盖其他标准调度程序

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);
}

这首先不能工作,因为我没有使用计算调度器。无论如何,即使我重写了其他调度器,结果也与我在test2中得到的结果相同。我编辑了我的问题。请看interval的文档。您将看到,该间隔使用默认的调度程序。默认的调度程序是计算。如果未调用订阅服务器,则可能使用了其他计划程序。因此,您需要阻止JUnit Runner线程,这样该方法就不会失败并中断JVM。我为test2添加了一个示例,该示例正在运行,并提供了一些解释。这首先不能工作,因为我没有使用计算调度器。无论如何,即使我重写了其他调度器,结果也与我在test2中得到的结果相同。我编辑了我的问题。请看interval的文档。您将看到,该间隔使用默认的调度程序。默认的调度程序是计算。如果未调用订阅服务器,则可能使用了其他计划程序。因此,您需要阻止JUnit Runner线程,这样该方法就不会失败并中断JVM。