Il test, sebbene possa richiedere molto tempo, è un passaggio importante nel ciclo di sviluppo di qualsiasi applicazione. Ti assicura di rilevare bug e problemi in anticipo prima di inviare il codice alla produzione.

Puoi utilizzare Jest per testare un'API Express Rest. Dopo aver creato una semplice API CRUD, scopri come scrivere test per ciascun endpoint.

Cos'è Jest?

Esistono molte librerie di test JavaScript tra cui puoi scegliere, ma Scherzo è il più facile per iniziare. È una libreria di test sviluppata da Facebook, utilizzata principalmente per testare i progetti React. Tuttavia, puoi anche usarlo per testare Node e altri progetti basati su JavaScript. È stato sviluppato su Jasmine, un altro strumento di test, e viene fornito in bundle con la propria libreria di asserzioni.

Anche se non avrai bisogno di una libreria di asserzioni per scrivere test in Jest, dovrai utilizzare uno strumento per effettuare richieste HTTP. Questo articolo utilizza SuperTest.

Cos'è il SuperTest?

Supertest è una libreria di test dei nodi per le chiamate HTTP. Estende la libreria di test dei superagenti e consente di effettuare richieste come GET, POST, PUT e DELETE.

instagram viewer

SuperTest fornisce un oggetto richiesta che puoi utilizzare per effettuare richieste HTTP.

cost richiesta = richiedere("supertest")
richiesta("https://icanhazdadjoke.com")
.ottenere('/slack')
.fine(funzione(ehm, ris) {
Se (errare) gettare erra;
consolle.tronco d'albero(ris.corpo.allegati);
});

Qui passi l'URL di base dell'API all'oggetto della richiesta e quindi concateni il metodo HTTP con il resto dell'URL. Il fine() il metodo chiama il server API e la funzione di callback gestisce la sua risposta.

Una volta ottenuta la risposta dall'API, puoi utilizzare Jest per convalidarla.

Crea un'API Express

Per testare i tuoi endpoint API, devi creare un'API REST primo. L'API che creerai è abbastanza semplice. Inserisce, recupera, aggiorna ed elimina elementi da un array.

Inizia creando una nuova directory chiamata node-jest e inizializzando npm.

mkdir node-jest
npm init -y

Quindi, crea un nuovo file chiamato index.js e creare il server Express.

cost espresso = richiedere("esprimere")
cost app = espresso()
app.ascolta (3000, () => console.log("Ascolto alla porta 3000"))

Testare l'endpoint GET /todos

Il primo endpoint che creerai è l'endpoint GET /todos. Restituisce tutti gli elementi nell'array. In index.js, aggiungi quanto segue.

cost cose da fare = [
];
// Ottieni tutte le cose da fare
app.get("/todos", (richiesto, ris) => {
Restituzioneris.stato(200).json({
dati: todos,
errore: nullo,
});
});

Si noti che la risposta ha un codice di stato 200 e un oggetto JSON contenente l'elemento da fare in un array chiamato data e un messaggio di errore. Questo è ciò che testerai usando Jest.

Ora installa Jest e SuperTest:

npm installare scherzo supertest

Quindi, aggiungi uno script di test in pacchetto.json come segue:

{
"script": {
"test": "scherzo"
}
}

Prima di iniziare a scrivere i tuoi test, dovresti capire come scrivere un test di base in Jest.

Considera la seguente funzione:

funzionesomma(a, b) {
Restituzione a + b;
}
modulo.esportazioni = somma;

Nel file di prova, devi:

  • Importa la funzione.
  • Descrivi cosa dovrebbe fare il test.
  • Chiama la funzione.
  • Asserire la risposta prevista con la risposta effettiva della funzione.
cost { somma } = richiedere("./somma")
descrivere("Somma di due elementi", asincrono() => {
test("Dovrebbe tornare 4", () => {
aspettare(somma(2,2)).essere(4)
})
})

Il descrivere la parola chiave specifica il gruppo di test e la test istruzione specifica il test specifico. Se il valore restituito dalla funzione corrisponde al valore passato essere, il test è superato.

Durante il test degli endpoint API, non chiamerai una funzione ma invierai una richiesta utilizzando SuperTest o un'altra libreria client HTTP.

Tornando all'endpoint GET, creare un nuovo file chiamato api.test.js. Qui è dove scriverai tutti i test degli endpoint. Denominare il file di prova con a .test infix assicura che Jest lo riconosca come un file di prova.

In api.test.js, importa supertest e imposta l'URL di base in questo modo:

cost richiesta = richiedere("supertest")
cost baseURL = "http://host locale: 3000"

Quindi, crea il primo test nel blocco di descrizione:

descrivere("OTTIENI /todos", () => {
cost nuovoTodo = {
id: cripto.UUID casuale(),
elemento: "Bere acqua",
completato: falso,
}
prima di tutto(asincrono () => {
// imposta la cosa da fare
attendi richiesta (baseURL).post("/todo").invia (nuovoTodo);
})
Dopotutto(asincrono () => {
aspettare richiesta (baseURL).delete(`/da fare/${nuovoTodo.id}`)
})
esso("dovrebbe restituire 200", asincrono () => {
cost risposta = aspettare richiesta (baseURL).get("/todos");
aspettare(risposta.codice di stato).essere(200);
aspettare(risposta.corpo.errore).essere(nullo);
});
esso("dovrebbe tornare todos", asincrono () => {
cost risposta = aspettare richiesta (baseURL).get("/todos");
aspetta (response.body.data.length >= 1).essere(VERO);
});
});

Prima di eseguire i test, sarà necessario definire le funzioni di configurazione e smontaggio. Queste funzioni popoleranno l'array todo con un elemento prima del test ed elimineranno i dati fittizi dopo ogni test.

Il codice che viene eseguito prima di tutti i test è nella funzione beforeAll(). Il codice che viene eseguito dopo tutti i test si trova nella funzione afterAll().

In questo esempio, stai semplicemente raggiungendo gli endpoint POST e DELETE per ciascuno. In un'applicazione reale, probabilmente ti connetteresti a un database fittizio contenente i dati del test.

In questo test, hai prima effettuato una richiesta all'endpoint GET /todos e hai confrontato la risposta inviata ai risultati previsti. Questa suite di test passerà se la risposta ha un Codice di stato HTTP di 200, i dati non sono vuoti e il messaggio di errore è nullo.

Testare l'endpoint POST /todo

In index.js, crea l'endpoint POST /todo:

app.post("/todo", (richiesto, ris) => {
Tentativo {
cost { id, articolo, completato } = req.body;
cost nuovoTodo = {
id,
elemento,
completato,
};
todos.spingere(nuovoTodo);
Restituzioneris.stato(201).json({
dati: todos,
errore: nullo,
});
} presa (errore) {
Restituzioneris.stato(500).json({
dati: nullo,
errore: errore,
});
}
});

In questo test, dovrai inviare i dettagli delle cose da fare nel corpo della richiesta usando il metodo send().

richiesta (baseURL).post("/todo").invia (nuovoTodo)

La richiesta POST /todo dovrebbe restituire un codice di stato 201 e l'array todos con il nuovo elemento aggiunto alla fine. Ecco come potrebbe essere il test:

descrivere("POST /da fare", () => {
cost nuovoTodo = {
// da fare
}
Dopotutto(asincrono () => {
aspettare richiesta (baseURL).delete(`/da fare/${nuovoTodo.id}`)
})
esso("dovrebbe aggiungere un elemento all'array todos", asincrono () => {
cost risposta = aspettare richiesta (baseURL).post("/todo").send(newTodo);
cost lastItem = response.body.data[response.body.data.length-1]
aspettare(risposta.codice di stato).essere(201);
aspettare(lastItem.elemento).essere(nuovoTodo["elemento"]);
aspettare(lastItem.completato).essere(nuovoTodo["completato"]);
});
});

Qui stai passando i dati todo al metodo send() come argomento. La risposta dovrebbe avere un codice di stato 201 e contenere anche tutte le cose da fare in un oggetto dati. Per verificare se todo è stato effettivamente creato, controlla se l'ultima voce nelle cose da fare restituite corrisponde a quella che hai inviato nella richiesta.

L'endpoint PUT /todos/:id dovrebbe restituire l'elemento aggiornato:

app.put("/todos/:id", (richiesto, ris) => {
Tentativo {
cost id = req.params.id
cost todo = todos.find((todo) => todo.id == id);
se (! da fare) {
gettarenuovoErrore("Todo non trovato")
}
todo.completed = req.body.completed;
Restituzioneris.stato(201).json({
dati: da fare,
errore: nullo,
});
} presa (errore) {
Restituzioneris.stato(500).json({
dati: nullo,
errore: errore,
});
}
});

Testare la risposta come segue:

descrivere("Aggiorna una cosa da fare", () => {
cost nuovoTodo = {
// da fare
}
prima di tutto(asincrono () => {
attendi richiesta (baseURL).post("/todo").invia (nuovoTodo);
})
Dopotutto(asincrono () => {
aspettare richiesta (baseURL).delete(`/da fare/${nuovoTodo.id}`)
})
esso("dovrebbe aggiornare l'elemento se esiste", asincrono () => {
cost risposta = aspettare richiesta (baseURL).put(`/todos/${nuovoTodo.id}`).inviare({
completato: VERO,
});
aspettare(risposta.codice di stato).essere(201);
aspettare(risposta.corpo.dati.completato).essere(VERO);
});
});

Il valore completato nel corpo della risposta dovrebbe essere true. Ricorda di includere l'ID dell'elemento che desideri aggiornare nell'URL.

Testare l'endpoint DELETE /todos/:id

In index.js, crea l'endpoint DELETE. Dovrebbe restituire i dati delle cose da fare senza l'elemento eliminato.

app.delete("/todos/:id", (richiesto, ris) => {
Tentativo {
cost id = req.params.id
cost da fare = da fare[0]
se (fare) {
todos.giunta(id, 1)
}
Restituzioneris.stato(200).json({
dati: todos,
errore: nullo,
});
} presa (errore) {
Restituzioneris.stato(500).json({
dati: nullo,
errore: errore,
});
}
});

Per testare l'endpoint, puoi verificare se l'elemento eliminato esiste ancora nei dati restituiti:

descrivere("Elimina una cosa da fare", () => {
cost nuovoTodo = {
// da fare
}
prima di tutto(asincrono () => {
attendi richiesta (baseURL).post("/todo").invia (nuovoTodo);
})
esso("dovrebbe eliminare un elemento", asincrono () => {
cost risposta = aspettare richiesta (baseURL).delete(`/todos/${nuovoTodo.id}`);
cost todos = risposta.body.data
cost esiste = todos.find (todo => {
newTodo.id == todoId
})
aspettarsi (esiste).toBe(non definito)
});
});

I dati restituiti dall'endpoint DELETE non devono contenere l'elemento eliminato. Poiché gli elementi restituiti si trovano in un array, puoi utilizzare Array[id] per verificare se l'API ha eliminato l'elemento correttamente. Il risultato dovrebbe essere falso.

Creazione di API REST

In questo articolo, hai appreso come testare un'API Express Rest utilizzando l'API Jest. Hai scritto dei test per le richieste HTTP GET, PUT, POST e DELETE e hai visto come inviare i dati all'endpoint nell'URL e nella richiesta. Dovresti essere in grado di applicare questa conoscenza durante il test della tua API Rest.