Tester är viktiga; De ger skydd för dina applikationer eller API: er. Som nybörjare är det möjligt att vara omedveten om behovet av att skriva tester som täcker de viktiga delarna av det du bygger. Ändå kommer du att träffas med det som du gör framsteg som utvecklare.
I en tidigare handledning lärde du dig att bygga ett API med Node.js. Om du inte har gått igenom det, föreslår jag att du gör det innan du fortsätter med det här. I den här handledningen skrivs du tester för ett API byggt med Node.js och Express. I slutet av denna handledning kommer du att veta hur testningen fungerar i Node.js, och du kommer att kunna bygga funktionella och testade API: er.
Du kommer att använda Mocha, Expect och Supertest.
Mocka är ett JavaScript-testramverk som gör asynkron testning enkelt och roligt. Mocka kommer med massor av bra funktioner som finns på hemsidan. Du kommer att utnyttja en handfull av dem.
Förvänta är ett påståendebibliotek som gör det enkelt för dig att göra bättre påståenden. Du kommer att se hur det fungerar. Supertest ger en hög abstraktion för testning av HTTP. Detta är nödvändigt eftersom du kommer att testa ett API.
Nogsamtal, tid att skriva en kod.
Jag har ett to-do list-projekt som redan är upprättat för dig. Modellen, konfigurationsfilen och en del av app.js är redan gjorda för dig. Gå över till GitHub och klona förvaret. Eller du kan helt enkelt göra:
git klon https://github.com/izuchukwu1/node-todo-api.git
Din package.json ska se ut så här.
# paket.json "namn": "nod-todo-api", "version": "1.0.0", "beskrivning": "", "main": "server.js", "scripts" starta ":" nodserver / server.js "," test ":" export NODE_ENV = test || SET \ "NODE_ENV = test \" && mocha server / ** / *. test.js "," test-watch " : "nodemon - exec 'npm test" "," motorer ": " nod ":" 8.0.0 "," nyckelord ": []," författare ":" "," licens ":" ISC " , "beroenden": "body-parser": "^ 1.17.2", "express": "^ 4.15.3", "lodash": "^ 4.17.4", "mongodb": "^ 2.2.29 "," mongoose ":" ^ 4.11.1 "," devDependencies ": " förvänta ":" ^ 1.20.2 "," mocha ":" ^ 3.4.2 "," nodemon ":" ^ 1.11.0 "," supertest ":" ^ 3.0.0 "
Kör nu kommandot för att installera beroenden.
npm installera
För ditt test, skapa en ny mapp som heter testa; den här mappen ska vara i din server katalogen. Skapa nu en ny fil där du ska skriva ditt test. Namnge filen server.test.js.
I den här filen börjar du med att kräva modulerna du installerade. Du måste också kräva din serverfil och din modell.
const. = test / server ') const Todo = kräver (' ./ ... / models / todo ')
Du måste ha några doser som ska användas under test. Men dessa till-dos kommer att raderas från testdatabasen varje gång du kör din testpaket. För att hantera det, skapa två tester som så.
# server / test / server.test.js const todos = [_id: nytt ObjectId (), text: "First test todo", _id: nytt ObjectId (), text: "Second test todo" , completedAt: 333] beforeEach ((done) => Todo.remove , sedan (() => returnera Todo.insertMany (todos)) )
Det tidigare blocket rensar din Todo-databas och lägger sedan in doseringssatsen ovan. Detta säkerställer att du har en stabil mängd poster i din databas så att dina test inte löser problem.
Med det gjort kan du skriva testet för POSTA begäran. För din POSTA begäran, kommer du att skriva två tester. Den första kommer att göra en förfrågan om ett giltigt att göra och vara framgångsrik. Den andra kommer att göra en förfrågan med en ogiltig kropp, och detta ska inte skapa ett nytt att göra.
Här är vad testet ska se ut.
# server / test / server.test.js beskriver ('POST / todos', () => // 1 det ('ska skapa en ny todo', (done) => let text = 'Test todo text' // 2 förfrågan (app) // 3 .post ('/ todos') .send (text) .expect (200) .expect ((res) => expect (res.body.text) .toBe text)) .end ((err, res) => // 4 om (err) return done (err) Todo.find (text). då ((todos) => // 5 förvänta (todos.length) .toBe (1) expect (todos [0] .text) .toBe (text) done ()) catch ((e) => gjort (e))) skapa inte med ogiltiga kroppsdata ", (gjort) => // 6 begäran (app) // 7 .post ('/ todos') .send () .expect (400) .end ( res) => om (err) return done (err) Todo.find (). då ((todos) => // 8 förvänta (todos.length) .toBe (2) done ()). fånga (e) => gjort (e)))))
Kör testet med kommandot:
npm-körtest
Det borde misslyckas. Här är vad som händer:
text
.För att få detta test passerar, gå till din server.js fil och släpp i koden som behövs för POST-förfrågan.
# server / server.js app.post ('/ todos', (req, res) => let todo = new Todo (text: req.body.text) todo.save () => res.send (doc), (e) => res.status (400) .send (e)))
Detta är enkelt - testet bör returnera längden på dosen som finns tillgänglig i databasen. Som du redan vet bör längden på todos vara 2. Varför? Du gissade rätt. I början av testpaketet skapade du en beforeEach
blockera det som rensar din databas och lägger in ny till-dos varje gång testpaketet körs.
För att testa att begäran om att få allt till-dos fungerar, här är koden för det.
# server / test / server.test.js beskriver ('GET / todos', () => it ('ska få alla todos', (done) => request (app) .get ('/ todos') .expect (200) .expect ((res) => (förvänta (res.body.todos.length) .toBe (2)) .end (gjort)))
I ovanstående gör du en SKAFFA SIG begäran till / todos väg. Den här gången passerar du inte något som begäran, eftersom det är a SKAFFA SIG begäran. Du förväntar dig att få ett svar med statuskoden för 200. Då räknar du med att längden på dosen kommer att vara 2.
När du kör testet ska du få ett fel. Försök få felet att skicka på egen hand.
Jag slår vad om att du fick det att fungera. Här är koden för att få testet att passera; jämför det med din lösning.
# server / server.js app.get ('/ todos', (req, res) => Todo.find (). då ((todos) => res.send (todos), => res.status (400) .send (e)))
När en SKAFFA SIG begäran lämnas till / todos sökväg, du vill hitta alla saker i Todo-samlingen och returnera dem som till-dos. Lägger till detta till server.js får testet att passera.
Därefter ska du skriva tre tester för SKAFFA SIG begäran om att hämta individuell dosering. Den första ska hämta och returnera uppgiften. Den andra och tredje ska återvända 404 fel i fall där handlingen inte hittas.
Öppna din server.test.js och skapa ett nytt beskrivningsblock med det första testfallet.
# server / server.test.js beskriver ('GET / todos /: id', () => det ('ska returnera doc doc', (done) => request (app) .get ('/ todos / $ todos [0] ._ id.toHexString () ') .expect (200) .expect ((res) => expect (res.body.todo.text) .toBe (todos [0] .text) ) .end (gjort))
Detta test gör en SKAFFA SIG begära att hämta den första åtgärd som finns tillgänglig i din databas. Du förväntar dig att få en 200 statuskod, och kontrollera att textvärdet för uppgiften är detsamma som det som skapades.
Nästa test ser ut så här.
('returnerar 404 om todo inte hittas', (gjort) => let _id = nytt ObjectId ('5967989ee978311656e93a59') begäran (app) .get ('/ todos / $ todos / _id.toHexString () ') .expect (404) .end (done))
Här letar du efter en uppgift med ett ID som inte motsvarar ID-en för alla som sparas i din databas. Testet förväntar sig att denna begäran ska returnera en 404 fel.
Det sista testet är som det första men lite annorlunda; här är hur det ser ut.
det ('ska returnera 404 för icke-objekt-ID', (gjort) => let hexId = '5967989ee978311656e93a5312' begäran (app) .get ('/ todos / $ todos / hexId') .expect (404). slutet (gjort)))
Här skapar du ett ogiltigt ObjectId
och försök att fråga databasen för att få en att göra som matchar ObjectId
skapats. Testet förväntar sig att begäran om att returnera a 404 fel.
När du kör testet ska de alla misslyckas. För att få dem att passera, lägg till koden nedan till din server.js fil.
# server / server.js app.get ('/ todos /: id', (req, res) => låt id = req.params.id // 1 om (! ObjectId.isValid (id)) // 2 returnera res.status (404) .send ('ID är inte giltigt') Todo.findById (id) .then ((todo) => if (! Todo) // 3 return res.status (404) .send () res.send (todo // //). fångst ((e) => res.status (400) .send ()))
findById
metod. Om det inte finns något att göra med det ID, a 404 fel skickas.Kör testkommandot en gång till, och det ska gå över.
Testet för din RADERA Förfrågan kommer att vara lite som vad du har för din GET-förfrågan.
Först vill du testa att en att göra är raderad.
# server / test / server.test.js beskriver ('DELETE / todos /: id', () => it ('ska ta bort en todo', (done) => låt hexId = todos [0] ._ id .toHexString () // 1 begäran (app) .delete ('/ todos / $ hexId') .expect (200) .expect ((res) => förvänta (res.body.todo._id) .toBe (hexId)) .end ((err, res) => // 2 om (err) return done (err)) Todo.findById (hexId) .then ((todo) => // 3 förvänta (todo.hexId) .toNotExist () gjort ()). fånga ((e) => gjort (e)))
Här är vad som händer ovan:
hexId
. Därefter a RADERA Förfrågan görs till sökandens sökväg, med hjälp av ID. Du förväntar dig att få en 200 svaret och den uppgift som erhållits för att matcha värdet av hexId
.hexId
. Sedan a RADERA Förfrågan har tidigare skickats, testet förväntar sig att det att göra som matchar det ID inte existerar.Därefter vill du testa att när en begäran görs för att radera ett uppdrag som inte existerar innehåller svaret a 404 fel. Det är viktigt att ha detta, eftersom det inte är möjligt att ta bort en handling två gånger. Så här ska testet för detta se ut.
# server / test / server.test.js det ('ska returnera 404 om todo inte hittas', (done) => let hexId = ny ObjectId (). toHexString () begäran (app) .delete ('/ todos / $ todos / hexId ') .expect (404) .end (gjort))
Detta skapar ett ID för en uppgift som inte finns i databasen. Då en RADERA Förfrågan görs för att ta bort uppgiften. Testet förväntas returnera a 404 ett fel eftersom handlingen inte existerar.
Du vill testa det a RADERA använder ett ogiltigt ID returnerar a 404 fel, som så.
# server / test / server.test.js det ('ska returnera 404 för icke-objekt ids', (gjort) => request (app) .delete ('/ todos / 123abc') .expect (404). (Gjort) ) )
För att få testet att passera, öppna din server.js och släpp det här.
# server / server.js app.delete ('/ todos /: id', (req, res) => låt id = req.params.id om (! ObjectId.isValid (id)) return res.status 404) .send () Todo.findByIdAndRemove (id) .then ((todo) => if (! Todo) return res.status (404) .send () res.send (todo)) .catch ((e) => res.status (400) .send ()))
Kör kommandot för att testa:
npm-körtest
Och dina tester ska passera.
Nu vet du hur du konfigurerar en testpaket när du bygger ett API med Node.js. Du har använt Mocha, Expect och Supertest för att testa ett API. En fördel med att göra det här är att du inte behöver ställa upp Postman när du bygger ditt API. Med ditt test kan du lära känna vad som är trasigt.
Innan vi sätter ihop, notera att JavaScript har blivit ett av de faktiska språken för att arbeta på webben. Det är inte utan sina inlärningskurvor, och det finns gott om ramar och bibliotek för att hålla dig upptagen också. Om du letar efter ytterligare resurser att studera eller använda i ditt arbete, kolla vad vi har tillgängligt på Envato Market.
Med hjälp av vad du nu vet är du bra att utforska testningsvärlden.