Ako otestovať RxJava?

1. Prehľad

V tomto článku sa pozrieme na spôsoby testovania kódu napísaného pomocou RxJava.

Typický tok, ktorý vytvárame pomocou RxJava, pozostáva z Pozorovateľné a an Pozorovateľ. Pozorovateľný je zdroj údajov, ktorý je postupnosťou prvkov. Jeden alebo viac pozorovateľov sa prihlási na jeho odber, aby dostával emitované udalosti.

Pozorovateľ a pozorovateľné objekty sa zvyčajne vykonávajú v samostatných vláknach asynchrónnym spôsobom - čo sťažuje testovanie kódu tradičným spôsobom.

Našťastie RxJava poskytuje a TestSubscriber trieda, ktorá nám dáva možnosť testovať asynchrónny tok riadený udalosťami.

2. Testovanie RxJava - tradičný spôsob

Začnime príkladom - máme postupnosť písmen, ktorú chceme skomprimovať, s postupnosťou celých čísel od 1 vrátane.

Náš test by mal tvrdiť, že predplatiteľ, ktorý počúva udalosti emitované pozorovateľným zipsom, dostane písmená zazipované s celými číslami.

Napísanie takéhoto testu tradičným spôsobom znamená, že si musíme viesť zoznam výsledkov a aktualizovať ho od pozorovateľa. Pridanie prvkov do zoznamu celých čísel znamená, že naši pozorovatelia a pozorovatelia musia pracovať v rovnakom vlákne - nemôžu pracovať asynchrónne.

A tak by nám chýbala jedna z najväčších výhod RxJava - spracovanie udalostí v samostatných vláknach.

Takto by vyzerala táto obmedzená verzia testu:

Zoznam písmen = Arrays.asList ("A", "B", "C", "D", "E"); Zoznam výsledkov = nový ArrayList (); Observable observable = Pozorovateľné .from (písmená) .zipWith (Observable.range (1, Integer.MAX_VALUE), (reťazec, index) -> index + "-" + reťazec); observable.subscribe (results :: add); assertThat (results, notNullValue ()); assertThat (výsledky, hasSize (5)); assertThat (results, hasItems ("1-A", "2-B", "3-C", "4-D", "5-E"));

Agregujeme výsledky od pozorovateľa pridaním prvkov do a výsledky zoznam. Pozorovateľ a pozorovateľ pracuje v rovnakom vlákne, takže naše tvrdenie správne blokuje a čaká na a prihlásiť sa na odber () metóda na dokončenie.

3. Testovanie RxJava pomocou a TestSubscriber

RxJava prichádza s TestPredplatiteľ trieda, ktorá nám umožňuje písať testy, ktoré pracujú s asynchrónnym spracovaním udalostí. Toto je normálny pozorovateľ, ktorý sa hlási k pozorovateľnému.

V teste môžeme preskúmať stav a TestSubscriber a uplatniť tvrdenia týkajúce sa tohto stavu:

Zoznam písmen = Arrays.asList ("A", "B", "C", "D", "E"); Predplatiteľ TestSubscriber = nový TestSubscriber (); Observable observable = Pozorovateľné .from (písmená) .zipWith (Observable.range (1, Integer.MAX_VALUE), ((reťazec, index) -> index + "-" + reťazec)); pozorovateľný.subscribe (predplatiteľ); subscriber.assertCompleted (); subscriber.assertNoErrors (); subscriber.assertValueCount (5); assertThat (subscriber.getOnNextEvents (), hasItems ("1-A", "2-B", "3-C", "4-D", "5-E"));

Míňame a TestSubscriber inštancia na a prihlásiť sa na odber () metóda na pozorovateľnom. Potom môžeme preskúmať stav tohto predplatiteľa.

TestSubscriber má niekoľko veľmi užitočných metód tvrdenia ktoré použijeme na potvrdenie našich očakávaní. Predplatiteľ by mal dostať 5 emitovaných prvkov od pozorovateľa a my to tvrdíme zavolaním na assertValueCount () metóda.

Môžeme preskúmať všetky udalosti, ktoré predplatiteľ dostal volaním na getOnNextEvents () metóda.

Volá sa assertCompleted () metóda kontroluje, či je dokončený prúd, ku ktorému je pozorovateľ prihlásený. The assertNoErrors () metóda tvrdí, že pri prihlásení na odber streamu nedošlo k žiadnym chybám.

4. Testovanie očakávaných výnimiek

Niekedy v našom spracovaní, keď pozorovateľ emituje udalosti alebo pozorovateľ spracováva udalosti, dôjde k chybe. The TestSubscriber má špeciálnu metódu na preskúmanie chybového stavu - assertError () metóda, ktorá berie typ výnimky ako argument:

Zoznam písmen = Arrays.asList ("A", "B", "C", "D", "E"); Predplatiteľ TestSubscriber = nový TestSubscriber (); Observable observable = Pozorovateľné .from (písmená) .zipWith (Observable.range (1, Integer.MAX_VALUE), ((reťazec, index) -> index + "-" + reťazec)) .concatWith (Observable.error (nový RuntimeException ( "chyba v pozorovateľnom"))); pozorovateľný.subscribe (predplatiteľ); subscriber.assertError (RuntimeException.class); subscriber.assertNotCompleted ();

Vytvárame pozorovateľné, ktoré je spojené s iným pozorovateľným pomocou concatWith () metóda. Druhý pozorovateľný vhadzuje a RuntimeException pri vysielaní ďalšej udalosti. Môžeme preskúmať typ tejto výnimky na a TestSubsciber zavolaním na assertError () metóda.

Pozorovateľ, ktorý prijme chybu, zastaví spracovanie a skončí v nedokončenom stave. Tento stav môže skontrolovať assertNotCompleted () metóda.

5. Časové testovanie Pozorovateľné

Povedzme, že máme Pozorovateľné ktorá vysiela jednu udalosť za sekundu a chceme toto správanie otestovať pomocou a TestSubsciber.

Môžeme definovať časovo Pozorovateľné pomocou Observable.interval () metóda a zložiť a TimeUnit ako argument:

Zoznam písmen = Arrays.asList ("A", "B", "C", "D", "E"); Plánovač TestScheduler = nový TestScheduler (); Predplatiteľ TestSubscriber = nový TestSubscriber (); Pozorovateľné začiarknutie = Pozorovateľný.interval (1, TimeUnit.SECONDS, plánovač); Observable observable = Observable.from (písmená) .zipWith (zaškrtnutie, (reťazec, index) -> index + "-" + reťazec); pozorovateľný.subscribeOn (plánovač) .subscribe (predplatiteľ);

The zatrhnúť pozorovateľná bude každú jednu sekundu vysielať novú hodnotu.

Na začiatku testu sme v čase nula, teda náš TestSubscriber nebude dokončené:

subscriber.assertNoValues ​​(); subscriber.assertNotCompleted ();

Na napodobnenie plynutia času v našom teste musíme použiť a TestScheduler trieda. Toto jednosekundové prejdenie môžeme simulovať zavolaním advanceTimeBy () metóda na a TestScheduler:

scheduler.advanceTimeBy (1, TimeUnit.SECONDS);

The advanceTimeBy () metóda vytvorí pozorovateľnú produkciu jednej udalosti. Môžeme tvrdiť, že jedna udalosť bola vyvolaná volaním assertValueCount () metóda:

subscriber.assertNoErrors (); subscriber.assertValueCount (1); subscriber.assertValues ​​("0-A");

Náš zoznam písmená má v sebe 5 prvkov, takže keď chceme spôsobiť, aby pozorovateľný emitoval všetky udalosti, musí uplynúť 6 sekúnd spracovania. Na napodobnenie týchto 6 sekúnd použijeme advanceTimeTo () metóda:

scheduler.advanceTimeTo (6, TimeUnit.SECONDS); subscriber.assertCompleted (); subscriber.assertNoErrors (); subscriber.assertValueCount (5); assertThat (subscriber.getOnNextEvents (), hasItems ("0-A", "1-B", "2-C", "3-D", "4-E"));

Po napodobnení uplynulého času môžeme vykonávať tvrdenia o a TestSubscriber. Môžeme tvrdiť, že všetky udalosti boli vyvolané volaním assertValueCount () metóda.

6. Záver

V tomto článku sme skúmali spôsoby testovania pozorovateľov a pozorovateľných súborov v RxJava. Pozreli sme sa na spôsob testovania emitovaných udalostí, chýb a pozorovateľných údajov založených na čase.

Implementáciu všetkých týchto príkladov a útržkov kódu nájdete v projekte GitHub - jedná sa o projekt Maven, takže by malo byť ľahké ho importovať a spustiť tak, ako je.


$config[zx-auto] not found$config[zx-overlay] not found