Hvordan teste RxJava?

1. Oversikt

I denne artikkelen ser vi på måter å teste kode skrevet med RxJava.

Den typiske flyten vi lager med RxJava består av en Observerbar og en Observatør. Det observerbare er en kilde til data som er en sekvens av elementer. En eller flere observatører abonnerer på den for å motta sendte hendelser.

Vanligvis blir observatør og observerbare utført i separate tråder på en asynkron måte - som gjør koden vanskelig å teste på en tradisjonell måte.

Heldigvis, RxJava gir en Testabonnent klasse som gir oss muligheten til å teste asynkron, hendelsesdrevet flyt.

2. Testing av RxJava - den tradisjonelle måten

La oss starte med et eksempel - vi har en bokstavsekvens som vi ønsker å zip med en sekvens av heltall fra 1 inkludert.

Testen vår skal hevde at en abonnent som lytter til hendelser som sendes ut med observerbare glidelåser, mottas bokstaver med heltall.

Å skrive en slik test på en tradisjonell måte betyr at vi trenger å føre en liste over resultater og oppdatere den listen fra en observatør. Å legge til elementer i en liste over heltall betyr at våre observerbare og observatører trenger å jobbe i samme tråd - de kan ikke fungere asynkront.

Og så vil vi savne en av de største fordelene med RxJava - behandling av hendelser i separate tråder.

Slik ser den begrensede versjonen av testen ut:

Listebokstaver = 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 :: legg til); 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 å legge til elementer i en resultater liste. Observatøren og det observerbare fungerer i samme tråd, slik at påstanden vår blokkeres ordentlig og venter på en abonnere() metode for å fullføre.

3. Testing av RxJava ved bruk av a Testabonnent

RxJava kommer med en Testabonnent klasse som lar oss skrive tester som fungerer med en asynkron behandling av hendelser. Dette er en normal observatør som abonnerer på det observerbare.

I en test kan vi undersøke tilstanden til a Testabonnent og komme med påstander om den tilstanden:

Listebokstaver = 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 Testabonnent eksempel til en abonnere() metode på den observerbare. Så kan vi undersøke tilstanden til denne abonnenten.

Testabonnent har noen veldig nyttige påstandsmetoder som vi bruker for å validere våre forventninger. Abonnenten skal motta 5 sendte elementer av en observatør, og vi hevder at ved å ringe assertValueCount () metode.

Vi kan undersøke alle hendelser som en abonnent mottok ved å ringe getOnNextEvents () metode.

Ringer til assertCompleted () metoden sjekker om en strøm som observatøren abonnerer på er fullført. De assertNoErrors () metoden hevder at det ikke var noen feil under abonnementet på en strøm.

4. Testing av forventede unntak

Noen ganger i vår behandling, når en observerbar sender ut hendelser eller en observatør behandler hendelser, oppstår det en feil. De Testabonnent har en spesiell metode for å undersøke feiltilstand - assertError () metode som tar typen unntak som argument:

Listebokstaver = 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 ( "feil i observerbar"))); observerbar. abonner (abonnent); subscriber.assertError (RuntimeException.class); subscriber.assertNotCompleted ();

Vi lager det observerbare som er forbundet med et annet observerbart ved hjelp av concatWith () metode. Den andre observerbare kaster a RuntimeException mens du sender ut neste begivenhet. Vi kan undersøke en type unntak på en TestSubsciber ved å ringe assertError () metode.

Observatøren som mottar en feil, slutter å behandle og ender i en ikke fullført tilstand. Denne tilstanden kan kontrolleres av assertNotCompleted () metode.

5. Testing tidsbasert Observerbar

La oss si at vi har en Observerbar som avgir en hendelse per sekund, og vi vil teste atferden med en TestSubsciber.

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

Listebokstaver = 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 (scheduler) .subscribe (subscriber);

De sett kryss observerbar vil avgi en ny verdi hvert sekund.

I begynnelsen av en test er vi til tiden null, så vår Testabonnent blir ikke fullført:

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

For å etterligne tiden som går i testen, må vi bruke en Testplanlegger klasse. Vi kan simulere passet på ett sekund ved å ringe advanceTimeBy () metode på en Testplanlegger:

scheduler.advanceTimeBy (1, TimeUnit.SECONDS);

De advanceTimeBy () metoden vil gjøre en observerbar produsere en hendelse. Vi kan hevde at en hendelse ble produsert ved å kalle en assertValueCount () metode:

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

Vår liste over bokstaver har 5 elementer i seg, så når vi ønsker å få en observerbar til å sende ut alle hendelser, må 6 sekunders behandling passere. For å etterligne de seks sekundene bruker 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"));

Etter å ha etterlignet tiden som er gått, kan vi utføre påstander om en Testabonnent. Vi kan hevde at alle hendelser ble produsert ved å ringe assertValueCount () metode.

6. Konklusjon

I denne artikkelen undersøkte vi måter å teste observatører og observerbare i RxJava. Vi så på en måte å teste utsendte hendelser, feil og tidsbaserte observerbare ting på.

Implementeringen av alle disse eksemplene og kodebitene finnes i GitHub-prosjektet - dette er et Maven-prosjekt, så det skal være enkelt å importere og kjøre som det er.


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