Testen, hoewel het tijdrovend kan zijn, is een belangrijke stap in de ontwikkelingscyclus van elke applicatie. Het zorgt ervoor dat je bugs en problemen in een vroeg stadium opmerkt voordat je code naar productie pusht.
U kunt Jest gebruiken om een Express Rest API te testen. Nadat je een eenvoudige CRUD API hebt gemaakt, ontdek je hoe je tests schrijft voor elk eindpunt.
Wat is grap?
Er zijn veel JavaScript-testbibliotheken waaruit u kunt kiezen, maar Grap is het gemakkelijkst om mee te beginnen. Het is een testbibliotheek ontwikkeld door Facebook, meestal gebruikt om React-projecten te testen. U kunt het echter ook gebruiken om Node en andere op JavaScript gebaseerde projecten te testen. Het is ontwikkeld bovenop Jasmine, een andere testtool, en wordt geleverd met een eigen beweringenbibliotheek.
Hoewel je geen assertion-bibliotheek nodig hebt om tests in Jest te schrijven, moet je een tool gebruiken om HTTP-verzoeken te doen. In dit artikel wordt SuperTest gebruikt.
Wat is SuperTest?
SuperTest
is een Node-testbibliotheek voor HTTP-aanroepen. Het breidt de superagent-testbibliotheek uit en stelt u in staat verzoeken te doen zoals GET, POST, PUT en DELETE.SuperTest biedt een verzoekobject dat u kunt gebruiken om HTTP-verzoeken te doen.
const verzoek = vereisen("supertest")
verzoek("https://icanhazdadjoke.com")
.krijgen('/slack')
.einde(functie(fout, res) {
als (fout) gooien fout;
troosten.log(res.lichaam.bijlagen);
});
Hier geeft u de basis-URL van de API door aan het aanvraagobject en koppelt u vervolgens de HTTP-methode aan de rest van de URL. De einde() methode roept de API-server aan en de callback-functie handelt het antwoord af.
Zodra u het antwoord van de API hebt ontvangen, kunt u Jest gebruiken om het te valideren.
Een Express API maken
Om uw eigen API-eindpunten te testen, moet u maken: een REST-API eerst. De API die u gaat maken is vrij eenvoudig. Het voegt items in, haalt ze op, werkt ze bij en verwijdert ze uit een array.
Begin met het maken van een nieuwe map met de naam node-jest en het initialiseren van npm.
mkdir node-jest
npm init -y
Maak vervolgens een nieuw bestand met de naam index.js en maak de Express-server.
const express = vereisen("uitdrukken")
const app = express()
app.luisteren (3000, () => console.log("Luisteren op poort 3000"))
Test het GET /todos-eindpunt
Het eerste eindpunt dat u gaat maken, is het GET /todos-eindpunt. Het retourneert alle items in de array. Voeg in index.js het volgende toe.
const todo = [
];
// Alle taken ophalen
app.get("/todos", (req, res) => {
opbrengstres.toestand(200).json({
gegevens: taken,
fout: nul,
});
});
Merk op dat het antwoord de statuscode 200 heeft en een JSON-object met het taken-item in een array met de naam data en een foutmelding. Dit ga je testen met Jest.
Installeer nu Jest en SuperTest:
npm installeren grap supertest
Voeg vervolgens een testscript toe in pakket.json als volgt:
{
"scripts": {
"testen": "grap"
}
}
Voordat u begint met het schrijven van uw eigen tests, moet u weten hoe u een basistest in Jest schrijft.
Denk aan de volgende functie:
functiesom(een, b) {
opbrengst een + b;
}
module.exporteert = som;
In het testbestand moet u:
- Importeer de functie.
- Beschrijf wat de test moet doen.
- Roep de functie aan.
- Bevestig het verwachte antwoord met het daadwerkelijke antwoord van de functie.
const { som } = vereisen("./som")
beschrijven("Som van twee items", asynchrone() => {
testen("Het zou 4. moeten retourneren", () => {
verwachten(som(2,2)).zijn(4)
})
})
De beschrijven trefwoord specificeert de groep tests en de testen statement specificeert de specifieke test. Als de waarde die wordt geretourneerd door de functie overeenkomt met de waarde die is doorgegeven aan zijn, de test is geslaagd.
Bij het testen van API-eindpunten roept u geen functie aan, maar verzendt u een verzoek met SuperTest of een andere HTTP-clientbibliotheek.
Keer terug naar het GET-eindpunt en maak een nieuw bestand met de naam api.test.js. Hier schrijft u alle eindpunttests. Het testbestand een naam geven met a .testen infix zorgt ervoor dat Jest het herkent als een testbestand.
Importeer in api.test.js supertest en stel de basis-URL als volgt in:
const verzoek = vereisen("supertest")
const baseURL = "http:// lokale host: 3000"
Maak vervolgens de eerste test in het beschrijvingsblok:
beschrijven("GET /todos", () => {
const nieuweTodo = {
ID kaart: cryptovaluta.randomUUID(),
item: "Drink water",
voltooid: vals,
}
voor alles(asynchrone () => {
// stel de taak in
wacht op verzoek (baseURL).post("/todo").verzenden (nieuwe Todo);
})
ten slotte(asynchrone () => {
wachten verzoek (baseURL).delete(`/todo/${nieuweTodo.id}`)
})
het("moet 200 teruggeven", asynchroon () => {
const reactie = wachten verzoek (baseURL).get("/todos");
verwachten(antwoord.status code).zijn(200);
verwachten(antwoord.lichaam.fout).zijn(nul);
});
het("moet todos terugkeren", asynchroon () => {
const reactie = wachten verzoek (baseURL).get("/todos");
verwachten (respons.body.data.length >= 1).zijn(WAAR);
});
});
Voordat u de tests uitvoert, moet u setup- en demontagefuncties definiëren. Deze functies vullen de todo-array vóór de test met een item en verwijderen de dummy-gegevens na elke test.
De code die vóór alle tests wordt uitgevoerd, bevindt zich in de functie beforeAll(). De code die na alle tests wordt uitgevoerd, bevindt zich in de functie afterAll().
In dit voorbeeld bereikt u eenvoudig de POST- en DELETE-eindpunten voor elk. In een echte toepassing zou u waarschijnlijk verbinding maken met een nepdatabase die de testgegevens bevat.
In deze test heb je eerst een verzoek ingediend bij het GET /todos-eindpunt en het teruggestuurde antwoord vergeleken met de verwachte resultaten. Deze testsuite zal slagen als het antwoord een heeft HTTP-statuscode van 200 zijn de gegevens niet leeg en is het foutbericht nul.
Test het POST/todo-eindpunt
Maak in index.js het POST /todo-eindpunt:
app.post("/todo", (req, res) => {
proberen {
const { id, item, voltooid } = req.body;
const nieuweTodo = {
ID kaart,
item,
voltooid,
};
todos.duw(nieuwTodo);
opbrengstres.toestand(201).json({
gegevens: taken,
fout: nul,
});
} vangst (fout) {
opbrengstres.toestand(500).json({
gegevens: nul,
fout: fout,
});
}
});
In deze test moet u de taakdetails in de hoofdtekst van het verzoek verzenden met behulp van de methode send().
verzoek (baseURL).post("/todo").verzenden (nieuweTodo)
Het POST /todo-verzoek zou een 201-statuscode moeten retourneren en de todos-array met het nieuwe item aan het einde toegevoegd. Hier is hoe de test eruit zou kunnen zien:
beschrijven("POST /todo", () => {
const nieuweTodo = {
// Te doen
}
ten slotte(asynchrone () => {
wachten verzoek (baseURL).delete(`/todo/${nieuweTodo.id}`)
})
het("moet een item toevoegen aan de todos-array", asynchroon () => {
const reactie = wachten verzoek (baseURL).post("/todo").send(newTodo);
const lastItem = response.body.data[respons.body.data.length-1]
verwachten(antwoord.status code).zijn(201);
verwachten(laatste item.item).zijn(nieuwTodo["item"]);
verwachten(laatste item.voltooid).zijn(nieuwTodo["voltooid"]);
});
});
Hier geef je de todo-gegevens door aan de methode send() als argument. Het antwoord moet een statuscode 201 hebben en ook alle todo-items in een gegevensobject bevatten. Om te testen of de taak daadwerkelijk is gemaakt, controleert u of het laatste item in de geretourneerde taken overeenkomt met het item dat u in het verzoek hebt verzonden.
Het PUT /todos/:id eindpunt zou het bijgewerkte item moeten retourneren:
app.put("/todos/:id", (req, res) => {
proberen {
const id = vereiste.params.id
const todo = todos.find((todo) => todo.id == id);
if(!todo) {
gooiennieuweFout("Todo niet gevonden")
}
todo.completed = req.body.completed;
opbrengstres.toestand(201).json({
gegevens: doen,
fout: nul,
});
} vangst (fout) {
opbrengstres.toestand(500).json({
gegevens: nul,
fout: fout,
});
}
});
Test het antwoord als volgt:
beschrijven("Een taak bijwerken", () => {
const nieuweTodo = {
// Te doen
}
voor alles(asynchrone () => {
wacht op verzoek (baseURL).post("/todo").verzenden (nieuwe Todo);
})
ten slotte(asynchrone () => {
wachten verzoek (baseURL).delete(`/todo/${nieuweTodo.id}`)
})
het("moet het item bijwerken als het bestaat", asynchroon () => {
const reactie = wachten verzoek (baseURL).put(`/todos/${nieuweTodo.id}`).versturen({
voltooid: WAAR,
});
verwachten(antwoord.status code).zijn(201);
verwachten(antwoord.lichaam.gegevens.voltooid).zijn(WAAR);
});
});
De voltooide waarde in de antwoordtekst moet waar zijn. Vergeet niet om de id van het item dat u wilt bijwerken in de URL op te nemen.
Test het DELETE /todos/:id-eindpunt
Maak in index.js het DELETE-eindpunt. Het zou de todo-gegevens moeten retourneren zonder het verwijderde item.
app.delete("/todos/:id", (req, res) => {
proberen {
const id = vereiste.params.id
const todo = todo[0]
als (todo) {
todos.splice(ID kaart, 1)
}
opbrengstres.toestand(200).json({
gegevens: taken,
fout: nul,
});
} vangst (fout) {
opbrengstres.toestand(500).json({
gegevens: nul,
fout: fout,
});
}
});
Om het eindpunt te testen, kunt u controleren of het verwijderde item nog steeds bestaat in de geretourneerde gegevens:
beschrijven("Eén taak verwijderen", () => {
const nieuweTodo = {
// Te doen
}
voor alles(asynchrone () => {
wacht op verzoek (baseURL).post("/todo").verzenden (nieuwe Todo);
})
het("zou één item moeten verwijderen", asynchroon () => {
const reactie = wachten verzoek (baseURL).delete(`/todos/${nieuweTodo.id}`);
const todos = response.body.data
const bestaat = todos.find (todo => {
newTodo.id == todoId
})
verwachten (bestaat).toBe(ongedefinieerd)
});
});
De gegevens die door het DELETE-eindpunt worden geretourneerd, mogen het verwijderde item niet bevatten. Aangezien de geretourneerde items zich in een array bevinden, kunt u Array[id] gebruiken om te controleren of de API het item correct heeft verwijderd. Het resultaat zou vals moeten zijn.
REST API's maken
In dit artikel heb je geleerd hoe je een Express Rest API test met behulp van Jest API. Je hebt tests geschreven voor de HTTP-verzoeken GET, PUT, POST en DELETE en hebt gezien hoe je gegevens naar het eindpunt kunt sturen in de URL en het verzoek. Je zou deze kennis moeten kunnen toepassen bij het testen van je eigen Rest API.