android - How to test complex RxJava Observables -
i using rxjava in android project , i'm starting unit testing code.
i have following observable method i'm going test
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 done! " + someobject.tostring(); subscriber.onnext(finishedstring); subscriber.oncompleted(); } catch (exception e) { subscriber.onerror(e); } }); }
my test case looks following:
testsubscriber<boolean> testsubscriber = new testsubscriber<>(); classtotest.changemystring("teststring").subscribe(testsubscriber);
when debug code it's not reaching part here:
... .flatmap(teststring2 -> observable.create( subscriber -> { manager.setteststring2(teststring2); anotherclass .dosth2(teststring2) .subscribe( teststring3 -> { manager.setteststring3(teststring3); subscriber.onnext(success); }, subscriber::onerror, subscriber::oncompleted ); } ));
how can write unit test case? can't figure out, why it's not working...
thanks guys!
alban
instead of using directly schedulers, may want inject , use testscheduler
instead. allow controle executions. (as unit test, may complicated deal others schedulers)
for more information on testscheduler
: how 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)); } }
then in test, can inject testscheduler
instead :
@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 }
please note refactored code should avoid nested subscription.
Comments
Post a Comment