Utilizzo di redux-saga-plan per unit test

Spesso nello sviluppo di un nuovo applicativo la parte che viene più sottovalutata è quella riguardante i test.

In realtà, scrivere i test permette di scovare bug rapidamente con un’attività di debug molto più veloce. Questo porta lo sviluppatore a scrivere metodi con poche righe di codice, aumentando la possibilità del suo riutilizzo e rendendolo più facile da leggere, evitando i commenti che molto spesso non vengono aggiornati nel tempo.

In questo caso vedremo come effettuare unit test su un middleware molto importante di redux, redux-saga.

 

Le Redux Saga sono implementate come funzioni generatrici e permettono di gestire side-effect all’interno della nostra web app. Redux, infatti, gestisce lo stato applicativo in modo sincrono ed è per questo che se, ad esempio, vogliamo comunicare con il server di backend ci servirà usare un middleware come redux-saga.

Ma vediamo come effettuare dei test sulle saga.

Effettuando delle ricerche, mi sono imbattuto in diverse librerie che consentono di effettuare unit test ma alla fine ho scelto redux-saga-test-plan per la sua flessibilità e facilità d’uso.

Ecco un esempio:

1import { call, put, takeLatest } from "redux-saga/effects";
2import api from "./api";
3
4function* fetchUsersSaga() {
5 try {
6   const users = yield call(api.getUsers);
7   yield put({ type: "FETCH_USERS_SUCCESS", payload: users });
8 } catch (e) {
9   yield put({ type: "FETCH_USERS_FAIL", payload: e });
10 }
11}
12
13function* watchFetchUsersSaga() {
14 yield takeLatest("FETCH_USERS_REQUEST", fetchUsersSaga);
15}

 

In questo esempio proviamo a recuperare una lista di utenti tramite api.

Per poter testare il funzionamento possiamo fare il mock dell’api tramite il metodo provide messo a disposizione dalla libreria:

1import { expectSaga } from "redux-saga-test-plan";
2import api from "./api";
3
4it("fetches users", () => {
5 const users = ["Jeremy", "Tucker"];
6
7 return expectSaga(watchFetchUsersSaga)
8   .provide([[call(api.getUsers), users]])
9   .put({ type: "FETCH_USERS_SUCCESS", payload: users })
10   .dispatch({ type: "FETCH_USERS_REQUEST" })
11   .silentRun();
12});

 

Se invece volessimo testare la saga nel caso in cui l’api fallisce il codice sarà il seguente:

1import { expectSaga } from "redux-saga-test-plan";
2import { throwError } from "redux-saga-test-plan/providers";
3
4it("handles errors", () => {
5 const error = new Error("Whoops");
6
7 return expectSaga(watchFetchUsersSaga)
8   .provide([[call(api.getUsers), throwError(error)]])
9   .put({ type: "FETCH_USERS_FAIL", payload: error })
10   .dispatch({ type: "FETCH_USERS_REQUEST" })
11   .silentRun();
12});

 

Grazie a redux-saga-test-plan possiamo quindi testare le nostre saga in modo semplice e intuitivo, migliorando la solidità del nostro codice.

Altri esempi potete trovarli nella documentazione ufficiale redux-saga-test-plan.

Ultimi Articoli