Sådan testes RxJava?

1. Oversigt

I denne artikel vil vi se på måder at teste kode skrevet ved hjælp af RxJava.

Den typiske strømning, vi opretter med RxJava, består af en Observerbar og en Observer. Den observerbare er en kilde til data, der er en række af elementer. En eller flere observatører abonnerer på den for at modtage udsendte begivenheder.

Typisk udføres observatøren og observerbare i separate tråde på en asynkron måde - det gør koden svært at teste på en traditionel måde.

Heldigvis, RxJava giver en TestSubscriber klasse, som giver os mulighed for at teste asynkront, hændelsesdrevet flow.

2. Test af RxJava - den traditionelle måde

Lad os starte med et eksempel - vi har en række bogstaver, som vi vil zip med en række heltal fra og med 1.

Vores test skal hævde, at en abonnent, der lytter til begivenheder, der udsendes af observerbare zippede, modtager bogstaver, der er zip med heltal.

At skrive en sådan test på en traditionel måde betyder, at vi er nødt til at føre en liste over resultater og opdatere denne liste fra en observatør. Tilføjelse af elementer til en liste over heltal betyder, at vores observerbare og observatører har brug for at arbejde i samme tråd - de kan ikke arbejde asynkront.

Og så ville vi savne en af ​​de største fordele ved RxJava - behandling af begivenheder i separate tråde.

Sådan ser den begrænsede version af testen ud:

Listebogstaver = Arrays.asList ("A", "B", "C", "D", "E"); Listeresultater = ny ArrayList (); Observable observerable = Observable .from (letters) .zipWith (Observable.range (1, Integer.MAX_VALUE), (string, index) -> index + "-" + string); observerbar. abonner (resultater :: tilføj); assertThat (results, notNullValue ()); assertThat (resultater, hasSize (5)); assertThat (resultater, hasItems ("1-A", "2-B", "3-C", "4-D", "5-E"));

Vi samler resultater fra en observatør ved at føje elementer til en resultater liste. Observatøren og det observerbare arbejder i samme tråd, så vores påstand blokerer ordentligt og venter på en abonner () metode til afslutning.

3. Test af RxJava ved hjælp af en TestSubscriber

RxJava leveres med en Testabonnent klasse, der giver os mulighed for at skrive tests, der fungerer med en asynkron behandling af begivenheder. Dette er en normal observatør, der abonnerer på det observerbare.

I en test kan vi undersøge tilstanden for a TestSubscriber og fremsætte påstande om denne tilstand:

Listebogstaver = Arrays.asList ("A", "B", "C", "D", "E"); TestSubscriber-abonnent = ny TestSubscriber (); Observable observerable = Observable .from (letters) .zipWith (Observable.range (1, Integer.MAX_VALUE), ((string, index) -> index + "-" + string)); observerbar. abonner (abonnent); subscriber.assertCompleted (); subscriber.assertNoErrors (); subscriber.assertValueCount (5); assertThat (subscriber.getOnNextEvents (), hasItems ("1-A", "2-B", "3-C", "4-D", "5-E"));

Vi passerer en TestSubscriber eksempel til en abonner () metode på den observerbare. Så kan vi undersøge denne abonnents tilstand.

TestSubscriber har nogle meget nyttige påstande metoder som vi bruger til at validere vores forventninger. Abonnenten skal modtage 5 udsendte elementer af en observatør, og vi hævder at ved at ringe til assertValueCount () metode.

Vi kan undersøge alle begivenheder, som en abonnent modtog ved at ringe til getOnNextEvents () metode.

Ringer til assertCompleted () metode kontrollerer, om en stream, som observatøren abonnerer på, er afsluttet. Det assertNoErrors () metode hævder, at der ikke var nogen fejl under abonnement på en stream.

4. Test af forventede undtagelser

Nogle gange i vores behandling, når en observerbar udsender begivenheder eller en observatør behandler begivenheder, opstår der en fejl. Det TestSubscriber har en særlig metode til at undersøge fejltilstand - assertError () metode, der tager typen af ​​en undtagelse som et argument:

Listebogstaver = Arrays.asList ("A", "B", "C", "D", "E"); TestSubscriber-abonnent = ny TestSubscriber (); Observable observerable = Observable .from (letters) .zipWith (Observable.range (1, Integer.MAX_VALUE), ((string, index) -> index + "-" + string)) .concatWith (Observable.error (new RuntimeException ( "fejl i observerbar"))); observerbar. abonner (abonnent); subscriber.assertError (RuntimeException.class); subscriber.assertNotCompleted ();

Vi skaber det observerbare, der er forbundet med et andet, der kan observeres ved hjælp af concatWith () metode. Den anden observerbare kaster a RuntimeException mens du udsender næste begivenhed. Vi kan undersøge en type af denne undtagelse på en TestSubsciber ved at ringe til assertError () metode.

Den observatør, der modtager en fejl, ophører med at behandle og ender i en ikke-afsluttet tilstand. Denne tilstand kan kontrolleres af assertNotCompleted () metode.

5. Test af tidsbaseret Observerbar

Lad os sige, at vi har en Observerbar der udsender en begivenhed pr. sekund, og vi vil teste den adfærd med en TestSubsciber.

Vi kan definere en tidsbaseret Observerbar bruger Observable.interval () metode og bestå en TimeUnit som argument:

Listebogstaver = Arrays.asList ("A", "B", "C", "D", "E"); TestScheduler scheduler = ny TestScheduler (); TestSubscriber-abonnent = ny TestSubscriber (); Observable tick = Observable.interval (1, TimeUnit.SECONDS, scheduler); Observable observerable = Observable.from (letters) .zipWith (tick, (string, index) -> index + "-" + string); observerbar.subscribeOn (planlægger) .subscribe (abonnent);

Det kryds observerbar vil udsende en ny værdi hvert sekund.

I begyndelsen af ​​en test er vi på tidspunktet nul, så vores TestSubscriber vil ikke blive afsluttet:

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

For at efterligne tiden der går i vores test, skal vi bruge en TestScheduler klasse. Vi kan simulere det ene sekundspass ved at ringe til advanceTimeBy () metode på en TestScheduler:

scheduler.advanceTimeBy (1, TimeUnit.SECONDS);

Det advanceTimeBy () metode vil gøre en observerbar producere en begivenhed. Vi kan hævde, at en begivenhed blev produceret ved at kalde en assertValueCount () metode:

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

Vores liste over bogstaver har 5 elementer i det, så når vi ønsker at få en observerbar til at udsende alle begivenheder, skal der gå 6 sekunders behandling. For at efterligne de 6 sekunder bruger vi advanceTimeTo () metode:

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

Efter at have efterlignet den forløbne tid kan vi udføre påstande om en TestSubscriber. Vi kan hævde, at alle begivenheder blev produceret ved at ringe til assertValueCount () metode.

6. Konklusion

I denne artikel undersøgte vi måder at teste observatører og observerbare i RxJava. Vi så på en måde at teste udsendte begivenheder, fejl og tidsbaserede observationer på.

Implementeringen af ​​alle disse eksempler og kodestykker findes i GitHub-projektet - dette er et Maven-projekt, så det skal være let at importere og køre, som det er.


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