Testning, även om det kan vara tidskrävande, är ett viktigt steg i utvecklingscykeln för alla applikationer. Det säkerställer att du fångar buggar och problem tidigt innan du skickar kod till produktion.
Du kan använda Jest för att testa ett Express Rest API. När du har skapat ett enkelt CRUD API, upptäck hur du skriver tester för varje slutpunkt.
Vad är skämt?
Det finns många JavaScript-testbibliotek som du kan välja mellan, men Skoj är det enklaste att börja med. Det är ett testbibliotek utvecklat av Facebook, som mest används för att testa React-projekt. Du kan dock också använda den för att testa Node och andra JavaScript-baserade projekt. Det utvecklades ovanpå Jasmine, ett annat testverktyg, och levereras med sitt eget påståendebibliotek.
Även om du inte behöver ett påståendebibliotek för att skriva tester i Jest, måste du använda ett verktyg för att göra HTTP-förfrågningar. Den här artikeln använder SuperTest.
Vad är SuperTest?
SuperTest är ett nodtestbibliotek för HTTP-anrop. Det utökar superagenttestbiblioteket och låter dig göra förfrågningar som GET, POST, PUT och DELETE.
SuperTest tillhandahåller ett förfrågningsobjekt som du kan använda för att göra HTTP-förfrågningar.
konst begäran = behöva("supertest")
begäran("https://icanhazdadjoke.com")
.skaffa sig('/slack')
.slutet(fungera(fel, res) {
om (fela) kasta fela;
trösta.logga(res.kropp.bilagor);
});
Här skickar du bas-URL: t för API: t till förfrågningsobjektet och kedjar sedan HTTP-metoden med resten av URL: en. De slutet() metoden anropar API-servern och återuppringningsfunktionen hanterar dess svar.
När du får svaret från API: t kan du använda Jest för att validera det.
Skapa ett Express API
För att testa dina egna API-slutpunkter måste du skapa ett REST API först. API: et du kommer att skapa är ganska enkelt. Den infogar, hämtar, uppdaterar och tar bort objekt från en array.
Börja med att skapa en ny katalog som heter node-jest och initiera npm.
mkdir nod-skämt
npm init -y
Skapa sedan en ny fil som heter index.js och skapa Express-servern.
konst uttrycka = behöva("uttrycka")
konst app = express()
app.listen (3000, () => console.log("Lyssnar på port 3000"))
Testa GET /todos Endpoint
Den första slutpunkten du kommer att skapa är GET /todos-slutpunkten. Den returnerar alla objekt i arrayen. Lägg till följande i index.js.
konst todos = [
];
// Få alla uppgifter
app.get("/todos", (req, res) => {
lämna tillbakares.status(200).json({
data: todos,
fel: null,
});
});
Observera att svaret har en statuskod på 200 och ett JSON-objekt som innehåller att göra-objektet i en array som kallas data och ett felmeddelande. Detta är vad du kommer att testa med Jest.
Installera nu Jest och SuperTest:
npm Installera skämtiga supertest
Lägg sedan till ett testskript package.json som följer:
{
"skript": {
"testa": "skoj"
}
}
Innan du börjar skriva dina egna test bör du förstå hur du skriver ett grundläggande test i Jest.
Tänk på följande funktion:
fungerabelopp(a, b) {
lämna tillbaka a + b;
}
modul.export = summa;
I testfilen måste du:
- Importera funktionen.
- Beskriv vad testet ska göra.
- Ring funktionen.
- Bekräfta det förväntade svaret med det faktiska svaret från funktionen.
konst { summa } = behöva("./belopp")
beskriva("Summan av två objekt", async() => {
testa("Den borde återkomma 4", () => {
förvänta(belopp(2,2)).att vara(4)
})
})
De beskriva nyckelordet anger gruppen av tester och testa uttalandet anger det specifika testet. Om värdet som returneras från funktionen matchar värdet som skickas till att vara, testet klarar.
När du testar API-slutpunkter kommer du inte att anropa en funktion utan skicka en begäran med SuperTest eller ett annat HTTP-klientbibliotek.
Återgå till GET-slutpunkten, skapa en ny fil som heter api.test.js. Det är här du kommer att skriva alla slutpunktstester. Namnge testfilen med a .testa infix ser till att Jest känner igen den som en testfil.
Importera supertest i api.test.js och ställ in basadressen så här:
konst begäran = behöva("supertest")
konst baseURL = "http://localhost: 3000"
Skapa sedan det första testet i beskrivningsblocket:
beskriva("GET /todos", () => {
konst newTodo = {
id: krypto.randomUUID(),
Artikel: "Drick vatten",
avslutad: falsk,
}
föreAlla(asynkron () => {
// ställ in uppgiften
invänta begäran (baseURL).post("/todo").send (newTodo);
})
trots allt(asynkron () => {
vänta request (baseURL).delete(`/att göra/${newTodo.id}`)
})
Det("ska returnera 200", asynkron () => {
konst svar = vänta request (baseURL).get("/todos");
förvänta(svar.statusCode).att vara(200);
förvänta(svar.kropp.fel).att vara(null);
});
Det("bör returnera todos", asynkron () => {
konst svar = vänta request (baseURL).get("/todos");
förvänta (response.body.data.length >= 1).att vara(Sann);
});
});
Innan du kör testerna måste du definiera inställnings- och rivningsfunktioner. Dessa funktioner kommer att fylla att göra-arrayen med ett objekt före testet och radera dummydata efter varje test.
Koden som körs före alla tester finns i beforeAll()-funktionen. Koden som körs efter alla tester finns i afterAll()-funktionen.
I det här exemplet slår du helt enkelt POST- och DELETE-slutpunkterna för var och en. I en riktig applikation skulle du förmodligen ansluta till en skendatabas som innehåller testdata.
I det här testet gjorde du först en begäran till GET /todos-slutpunkten och jämförde svaret som skickades tillbaka med de förväntade resultaten. Denna testsvit kommer att godkännas om svaret har en HTTP-statuskod av 200 är data inte tomma och felmeddelandet är null.
Testa POST /todo Endpoint
Skapa POST /todo-slutpunkten i index.js:
app.post("/todo", (req, res) => {
Prova {
konst { id, item, completed } = req.body;
konst newTodo = {
id,
Artikel,
avslutad,
};
todos.tryck(newTodo);
lämna tillbakares.status(201).json({
data: todos,
fel: null,
});
} fånga (fel) {
lämna tillbakares.status(500).json({
data: null,
fel: fel,
});
}
});
I det här testet måste du skicka uppgifterna om att göra i begärandekroppen med metoden send().
request (baseURL).post("/todo").send (newTodo)
POST /todo-begäran bör returnera en 201-statuskod och todos-arrayen med den nya posten tillagd i slutet. Så här kan testet se ut:
beskriva("POST /todo", () => {
konst newTodo = {
// att göra
}
trots allt(asynkron () => {
vänta request (baseURL).delete(`/att göra/${newTodo.id}`)
})
Det("bör lägga till ett objekt i todos-arrayen", asynkron () => {
konst svar = vänta request (baseURL).post("/todo").send(newTodo);
konst lastItem = response.body.data[response.body.data.length-1]
förvänta(svar.statusCode).att vara(201);
förvänta(sista objektet.Artikel).att vara(newTodo["Artikel"]);
förvänta(sista objektet.avslutad).att vara(newTodo["avslutad"]);
});
});
Här skickar du uppgifterna att göra till metoden send() som ett argument. Svaret ska ha en 201-statuskod och även innehålla alla att göra-objekt i ett dataobjekt. För att testa om todo faktiskt skapades, kontrollera om den sista posten i de returnerade uppgifterna matchar den du skickade i begäran.
PUT /todos/:id-slutpunkten bör returnera det uppdaterade objektet:
app.put("/todos/:id", (req, res) => {
Prova {
konst id = req.params.id
konst todo = todos.find((todo) => todo.id == id);
if(!todo) {
kastanyFel("Todo hittades inte")
}
todo.completed = req.body.completed;
lämna tillbakares.status(201).json({
data: att göra,
fel: null,
});
} fånga (fel) {
lämna tillbakares.status(500).json({
data: null,
fel: fel,
});
}
});
Testa svaret enligt följande:
beskriva("Uppdatera en uppgift", () => {
konst newTodo = {
// att göra
}
föreAlla(asynkron () => {
invänta begäran (baseURL).post("/todo").send (newTodo);
})
trots allt(asynkron () => {
vänta request (baseURL).delete(`/att göra/${newTodo.id}`)
})
Det("bör uppdatera objektet om det finns", asynkron () => {
konst svar = vänta request (baseURL).put(`/todos/${newTodo.id}`).skicka({
avslutad: Sann,
});
förvänta(svar.statusCode).att vara(201);
förvänta(svar.kropp.data.avslutad).att vara(Sann);
});
});
Det ifyllda värdet i svarskroppen ska vara sant. Kom ihåg att inkludera id för objektet du vill uppdatera i URL: en.
Testa DELETE /todos/:id Endpoint
Skapa slutpunkten DELETE i index.js. Det bör returnera uppgiftsdata utan det raderade objektet.
app.delete("/todos/:id", (req, res) => {
Prova {
konst id = req.params.id
konst todo = todos[0]
if (todo) {
todos.splitsa(id, 1)
}
lämna tillbakares.status(200).json({
data: todos,
fel: null,
});
} fånga (fel) {
lämna tillbakares.status(500).json({
data: null,
fel: fel,
});
}
});
För att testa slutpunkten kan du kontrollera om det borttagna objektet fortfarande finns i den returnerade datan:
beskriva("Ta bort en uppgift", () => {
konst newTodo = {
// att göra
}
föreAlla(asynkron () => {
invänta begäran (baseURL).post("/todo").send (newTodo);
})
Det("bör ta bort ett objekt", asynkron () => {
konst svar = vänta request (baseURL).delete(`/todos/${newTodo.id}`);
konst todos = respons.kroppsdata
konst existerar = todos.find (todo => {
newTodo.id == todoId
})
förvänta (finns).toBe(odefinierad)
});
});
Data som returneras från DELETE-slutpunkten bör inte innehålla det raderade objektet. Eftersom de returnerade objekten finns i en array kan du använda Array[id] för att kontrollera om API: et har tagit bort objektet korrekt. Resultatet bör vara falskt.
Skapa REST API: er
I den här artikeln lärde du dig hur du testar ett Express Rest API med Jest API. Du skrev tester för HTTP-förfrågningarna GET, PUT, POST och DELETE och såg hur man skickar data till slutpunkten i URL: en och begäran. Du bör kunna tillämpa denna kunskap när du testar ditt eget Rest API.