<img height="1" width="1" src="https://www.facebook.com/tr?id=1272750026111903&amp;ev=PageView &amp;noscript=1">

5 tips for enhetstesting av React-komponenter

Karl Jørgen Overå

Karl Jørgen Overå | 01. september 2017

Enhetstesting av en moderne JavaScript web-applikasjon kan være vanskelig å komme i gang med. Ved å kombinere React med to kraftige test-verktøy er det raskt skrive gode enhetstester.

Pakkene vi skal bruke er:

  • Jest: Testkjører som eksekverer testene våre. Det har også funksjoner for stubbing og spying.
  • enzyme: Verktøy for å assertere, manipulere og traversere React-komponenter.

Har du lyst å komme i gang og teste eksemplene under her, så kan jeg anbefale create-react-app som kommer med Jest. Installer enzyme i tillegg så er du klar.

Eksemplene vil bestå av av en eller flere describe eller it, en typisk test fil vil importere React fra react og shallow eller mount fra enzyme.

Import React fra react

1. Test fleste komponenter ved bruk av shallow

Når vi enhetstester så er det viktig å holde seg mest mulig til hver enhet. I vårt tilfelle er dette React-komponenter. Dersom en komponent avhengig av andre komponenter eller funksjoner så er vi ikke interessert i å teste de i tillegg. Shallow gjør dette enklere for oss ved å ikke initiere opp under-komponenter, og kjører færre livssyklus-funksjoner

Shallow vil kalle componentDidMount ved instansiering og componentWillReceiveProps dersom man oppdaterer props med .setProps() manuelt. Denne oppførselen kan man skru av ved å sende inn tilleggsvalgene
{ disableLifeCycleMethods: true } til shallow.

Tilleggsvalg til Shallow

Bonustips: Bruk console.log(wrapper.debug()); til å se hvordan shallow representerer DOM-en til komponenten når du utvikler testene.

2. Eksekver kun det du tester

Test én og én funksjon i dine stateful-komponenter, disse kan nås via .instance(). Dette lar oss teste én og én funksjon i en komponent.

Eksekveringseksempel

3. Sjekk at ting faktisk har skjedd

Jest gir oss noen verktøy for å bekrefte at det vi vil skal skje — har skjedd. jest.spyOn(...) og jest.fn() er to verktøy som lar oss gjøre nyttige sjekker på handlinger innad en komponent.

Jest utility eksempel

4. Mocking og stubbing

Tre forskjellige måter å gjøre ting på, avhengig av hvordan komponenten din er satt opp. Vi kan gjøre det ved å sende inn jest.fn() mock-funksjoner, mutere instansen til komponenten med våre egne implementasjoner eller å stubbe ut importerte biblioteker.

4.1. Funksjoner som sendes inn som props

I eksempelvis en redux-tilkoblet komponent så er det enklest å teste en komponent om man går helt utenom redux. Her er et eksempel på hvordan å hente ut den ikke-tilkoblede komponenten, og gi den props som redux vanligvis ville hatt ansvaret for.

Eksempel på hvordan å hente ut ikke-tilkoblet komponent

4.2. Overskriv interne funksjoner for å redusere hva som testes

Vi har en stateful komponent som har to funksjoner, createPost og generateText, hvor createPost kaller på generateText. I dette scenarioet kan vi enkelt mocke ut generateText for å begrense testingen vår til createPost.

Overskrider metoder

4.3. Stubbing av eksterne biblioteker

Ekstern kode kan ofte være et problem i enhetstester. De kan være store og tunge ting som gjør at testene blir trege, eller til og med gjøre det umulig for oss å få testet.

Det kan enkelt løses ved å utnytte hvordan lasting av moduler fungerer i JavaScript.

Vi har en enkel komponent:

Komponent

Med tilhørende test:

Kodetest

Når vi kjører testen så blir crunchData fra biblioteket aldri eksekvert, som gjør testen vår lynrask, og vi tester kun funksjonaliteten i komponenten vår.

5. Testing av promises (ikke React-spesifikk)

Jeg foretrekker å holde fetching av data og transformering utenfor komponentene mine, men det er viktig å tenke over at man ikke alltid trenger Redux. Her er noen tips for håndtering av promises i enhetstester, både i og utenfor React-komponenter.

Vi tar utgangspunkt i en React komponent som henter litt data ved hjelp av fetch.

Fetching component

Man kan jo bli tilgitt for å tro at denne testen er umulig, eller i det minste veldig vanskelig å teste. Den gjør noe asynkront og den bruker nettverkskall! Men om vi skjønner hvordan Jest håndterer promises og hvordan vi mocker ut fetch, så blir denne veldig enkel å teste.

Dersom vi returerer et promise til Jest, så vil Jest vente til det promiset blir resolved eller rejected, fjerner vi fetch-kallet i tillegg så trenger den ikke å vente lenge. Følg kommentarene i kodesnutten under.

Kodesnutt bruk av promises

Håper du fant noen nyttige tips. Ser du noe feil eller er sterkt uenig, kontakt meg gjerne: karl.overaa@systek.no

 

Er du et kodetalent? Se ledige stillinger her

 

Del på sosiale medier: