如何测试复杂的RxJava observable



我在我的android项目中使用RxJava,我实际上开始单元测试我的代码。

我有下面的Observable方法我要测试

private Observable<Boolean> changeMyString (@NonNull String testString) {
    return OneClass
        .doSth1(testString)
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .flatMap(testString2 -> Observable.create(
            subscriber -> {
                manager.setTestString2(testString2);
                AnotherClass
                    .doSth2(testString2)
                    .subscribe(
                        testString3 -> {
                            manager.setTestString3(testString3);
                            subscriber.onNext(success);
                        },
                        subscriber::onError,
                        subscriber::onCompleted
                    );
            }
        ));

onecclass .java doSth1(String testString)

private Observable<Object> doSth1 (@NonNull String testString) {
    return Observable.create(subscriber -> {
        try {
            testString = "CHANGEDSTRING"
            subscriber.onNext(testString);
            subscriber.onCompleted();
        }
        catch (Exception e) {
            subscriber.onError(e);
        }
    });
}

AnotherClass.java doSth2(Object someObject)

    public Observable<String> doSth2 (@NonNull Object someObject) {
    return Observable.create(subscriber -> {
        String changeText = preferences.getString(ANYSTRING, null); //preferences = SharedPrefences
        if (StringHelper.isEmpty(changeText)) {
            subscriber.onCompleted();
            return;
        }
        try {
            String finishedString = "WE ARE DONE! " + someObject.toString();
            subscriber.onNext(finishedString);
            subscriber.onCompleted();
        }
        catch (Exception e) {
            subscriber.onError(e);
        }
    });
}

我的测试用例如下所示:

TestSubscriber<Boolean> testSubscriber = new TestSubscriber<>();
ClassToTest.changeMyString("TESTSTRING").subscribe(testSubscriber);

当我调试我的代码时,它没有到达这里的这一部分:

...
.flatMap(testString2 -> Observable.create(
        subscriber -> {
            manager.setTestString2(testString2);
            AnotherClass
                .doSth2(testString2)
                .subscribe(
                    testString3 -> {
                        manager.setTestString3(testString3);
                        subscriber.onNext(success);
                    },
                    subscriber::onError,
                    subscriber::onCompleted
                );
        }
    ));

我如何为这种情况编写单元测试?我不明白,为什么它不工作……

谢谢你的帮助!

奥尔本

与其直接使用scheduler,不如注入它并使用TestScheduler。它将允许你控制执行。(对于单元测试,处理其他调度器可能会比较复杂)

有关TestScheduler的更多信息:如何在RxJava中使用TestScheduler

 class YourClass {
        private final Scheduler ioScheduler;
        private final Scheduler uiScheduler;
        public YourClass(Scheduler ioScheduler, Scheduler uiScheduler) {
               this.ioScheduler = ioScheduler;
               this.uiScheduler = uiScheduler;
        }
        private Observable<Boolean> changeMyString (@NonNull String testString) {
         return OneClass.doSth1(testString)
                        .subscribeOn(ioScheduler)
                        .observeOn(uiScheduler)
                        .doOnNext(str -> manager.setTestString2(str))
                        .flatMap(testString2 -> AnotherClass
                        .doSth2(testString2))
                        .doOnNext(str -> manager.setString3(str));
         }
 }

那么在你的测试中,你可以注射一个TestScheduler代替:

   @Test
   public void example() {
          TestScheduler ui = new TestScheduler();
          TestScheduler io = new TestScheduler();
         YourClass hello = new YourClass(io, ui);
           TestSubscriber subscriber = new TestSubscriber();
           hello.changeMyString("stuff").subscribe(subscriber); 
         io.advanceByTime(2, SECONDS);
         ui.advanceByTime(2, SECONDS);
         // perform check on subscriber here
    }

请注意,我重构了你的代码,因为你应该避免嵌套订阅。

在onSubscribe中创建一个新的Observable流通常是一个坏主意。

你应该考虑这样做:

    OneClass
    .doSth1(testString)
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .doOnNext(testString2 -> manager.setTestString2(testString2))
    .flatMap(testString2 -> AnotherClass.doSth2(testString2))
    .doOnNext(testString3 -> manager.setTestString3(testString3))
    .map(setTestString3 -> true);

从我在你的代码中看到的,这应该给你你想要的

相关内容

  • 没有找到相关文章

最新更新