我在我的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
);
}
));
OneClass.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
);
}
));
如何为此案例编写单元测试?我无法弄明白,为什么它不起作用......
感谢您的帮助!
阿尔
答案 0 :(得分:2)
您可能希望将其注入并使用TestScheduler
而不是直接使用调度程序。它将允许你控制执行。 (对于单元测试,处理其他调度程序可能很复杂)
有关TestScheduler
:How to use TestScheduler in RxJava
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
}
请注意,我重构了您的代码,因为您应该避免嵌套订阅。
答案 1 :(得分:1)
在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);
从我在您的代码中看到的内容,这应该可以为您提供所需内容。