Testen einer Node.js-API

Einführung

Tests sind wichtig; Sie bieten einen Schutz für Ihre Anwendungen oder APIs. Als Anfänger können Sie die Notwendigkeit vergessen, Tests zu schreiben, die die wichtigen Teile Ihres Baus abdecken. Sie werden es jedoch treffen, wenn Sie als Entwickler Fortschritte machen.

In einem früheren Lernprogramm haben Sie erfahren, wie Sie eine API mit Node.js erstellen. Wenn Sie es nicht durchgemacht haben, schlage ich vor, dass Sie dies tun, bevor Sie fortfahren. In diesem Lernprogramm schreiben Sie Tests für eine API, die mit Node.js und Express erstellt wurde. Am Ende dieses Lernprogramms erfahren Sie, wie das Testen in Node.js funktioniert, und Sie können funktionale und getestete APIs erstellen.

Testwerkzeuge

Sie werden Mocha, Expect und Supertest verwenden.

Mokka ist ein JavaScript-Test-Framework, das das asynchrone Testen einfach und unterhaltsam macht. Mocha verfügt über eine Vielzahl toller Funktionen, die auf der Website zu finden sind. Sie werden eine Handvoll davon nutzen.

Erwarten von ist eine Assertionsbibliothek, mit der Sie leicht bessere Assertions erstellen können. Sie werden sehen, wie das funktioniert. Supertest bietet eine Abstraktion auf hoher Ebene zum Testen von HTTP. Dies ist erforderlich, da Sie eine API testen.

Genug geredet, Zeit, um Code zu schreiben.

Projektaufbau

Ich habe bereits ein To-Do-Listenprojekt für Sie eingerichtet. Das Modell, die Konfigurationsdatei und ein Teil der app.js sind bereits für Sie erledigt. Gehen Sie zu GitHub und klonen Sie das Repository. Oder Sie können einfach tun:

Git Klon https://github.com/izuchukwu1/node-todo-api.git

Ihr package.json sollte so aussehen.

# package.json "name": "node-todo-api", "version": "1.0.0", "description": "", "main": "server.js", "scripts": " start ":" node server / server.js "," test ":" export NODE_ENV = test || SET \ "NODE_ENV = test \" && Mokka-Server / ** / *. test.js "," test-watch " : "nodemon --exec 'npm test'", "engine": "node": "8.0.0", "Schlüsselwörter": [], "author": "", "license": "ISC" , "Abhängigkeiten": "Body-Parser": "^ 1.17.2", "express": "^ 4.15.3", "lodash": "^ 4.17.4", "mongodb": "^ 2.2.29 "," mongoose ":" ^ 4.11.1 "," devDependencies ": " erwarten ":" ^ 1.20.2 "," mocha ":" ^ 3.4.2 "," nodemon ":" ^ 1.11.0 "," Supertest ":" ^ 3.0.0 "

Führen Sie nun den Befehl aus, um die Abhängigkeiten zu installieren.

npm installieren

POST-Anforderungstest

Erstellen Sie für Ihren Test einen neuen Ordner mit dem Namen Prüfung; Dieser Ordner sollte sich in Ihrem Ordner befinden Server Verzeichnis. Erstellen Sie nun eine neue Datei, in der Sie Ihren Test schreiben werden. Benennen Sie die Datei server.test.js.

Beginnen Sie in dieser Datei, indem Sie die installierten Module anfordern. Sie müssen außerdem Ihre Serverdatei und Ihr Modell anfordern.

# server / test / server.test.js const erwartung ("erwartet") const request = required ('supertest') const ObjectId = requir ('mongodb') const app = required ('./… / server ') const Todo = erfordern (' ./… / models / todo ')

Sie benötigen einige Aufgaben, die während der Tests verwendet werden. Diese Aufgaben werden jedoch jedes Mal, wenn Sie Ihre Testsuite ausführen, aus der Testdatenbank gelöscht. Erstellen Sie dazu zwei Tests.

# server / test / server.test.js const todos = [_id: new ObjectId (), Text: "Erster Test-todo", _id: new ObjectId (), Text: "Zweiter Test-todo", abgeschlossen: wahr , completAt: 333] beforeEach ((done) => Todo.remove (). then (() => return Todo.insertMany (todos)). dann (() => done ()) )

Der Vorher-Block reinigt Ihre Todo-Datenbank und fügt dann den oben definierten Aufgabensatz ein. Dadurch wird sichergestellt, dass Sie über eine stabile Anzahl von Einträgen in Ihrer Datenbank verfügen, sodass bei Ihren Tests keine Probleme auftreten.

Danach können Sie den Test für das schreiben POST anfordern. Für dein POST Auf Anfrage schreiben Sie zwei Tests. Der erste wird eine Anfrage für eine gültige Aufgabe stellen und erfolgreich sein. Der zweite wird eine Anforderung mit einem ungültigen Hauptteil stellen, und dies sollte keine neuen Aufgaben erstellen.

So sollte der Test aussehen.

# server / test / server.test.js beschreiben ('POST / todos', () => // 1 it ('sollte ein neues todo erstellen', (done) => let text = 'ToDo-Text testen' // 2 request (app) // 3 .post ('/ todos') .send (text) .expect (200) .expect ((res) => expect (res.body.text) .toBe ( text)) .end ((err, res) => // 4 if (err) return done (err) Todo.find (text). dann ((todos) => // 5 erwartet (todos.length) .toBe (1) erwartet (todos [0] .text) .toBe (Text) done ()). catch ((e) => done (e)))) es ('sollte keine Aufgaben mit ungültigen Rumpfdaten erstellen ', (erledigt) => // 6 request (app) // 7 .post (' / todos ') .send () .expect (400) .end ((err, res) => if (err) return erledigt (err) Todo.find (). dann ((todos) => // 8 erwarten (todos.length) .toBe (2) done ()). catch ((e) => done (e)))))

Führen Sie den Test mit dem Befehl aus:

npm run test

Es sollte scheitern Hier ist was passiert:

  1. Beschreibt den Test.
  2. Erstellt eine neue Aufgabe und speichert sie als Wert im Text.
  3. Sie stellen eine POST-Anfrage an / todos Pfad Ihrer API. Senden Sie die von Ihnen erstellten Aufgaben als Hauptteil der Anforderung. Sie erwarten den Statuscode für die Anforderung 200 und der Körper der Aufgabe, um den Wert von Text.
  4. Wenn ein Fehler vorliegt, wird ein Fehler zurückgegeben, und die Anforderung wird beendet. Daher wird der nächste Codeblock nicht ausgeführt. Wenn kein Fehler auftritt, wird der Fluss fortgesetzt.
  5. Es wird eine Anfrage an die Datenbank gestellt, um die erstellten Aufgaben zu finden. Sie erwarten, dass die Länge der Aufgaben in der Datenbank 1 beträgt, und der Text der Aufgaben entspricht dem Wert des Textes.
  6. Dies ist der Test mit ungültigen Rumpfdaten.
  7. EIN POST Anfrage wird an die gestellt / todos Pfad. Diesmal senden Sie eine Anfrage ohne Text. Sie erwarten eine 400 anfordern. Sie müssen den Körper nicht überprüfen, da Sie keine senden. Wenn ein Fehler auftritt, wird er zurückgegeben und der Code wird nicht mehr ausgeführt.
  8. Wenn kein Fehler auftritt, wird an die Datenbank eine Anforderung zur Überprüfung der Länge der Aufgaben gestellt. Wir gehen davon aus, dass die Datenbank nur 2 enthalten wird. Dies sind die zu Beginn erstellten Aufgaben.

Um diesen Test zu bestehen, gehen Sie zu Ihrem server.js Datei und geben Sie den Code ein, der für die POST-Anforderung erforderlich ist.

# server / server.js app.post ('/ todos', (req, res) => let todo = new Todo (text: req.body.text) todo.save (). dann ((doc) => res.send (doc), (e) => res.status (400) .send (e)))

GET Request Test

Dies ist einfach: Der Test sollte die Länge der in der Datenbank verfügbaren Aufgaben anzeigen. Wie Sie bereits wissen, sollte die Länge der Aufgaben 2 betragen. Warum? Du hast richtig geraten. Am Anfang der Testsuite haben Sie eine erstellt vor jedem Block, der Ihre Datenbank bereinigt und bei jeder Ausführung der Testsuite neue Aufgaben einfügt.

Um zu testen, dass die Anforderung, alle Aufgaben zu erledigen, funktioniert, finden Sie hier den Code dafür.

# server / test / server.test.js beschreiben ('GET / todos', () => it ('sollte alle todos erhalten', (done) => request (app) .get ('/ todos') .expect (200) .expect ((res) => expect (res.body.todos.length) .toBe (2)) .end (done)))

In dem oben genannten machen Sie eine ERHALTEN Anfrage an die / todos Pfad. Dieses Mal übergeben Sie nichts als Hauptteil der Anforderung, da es sich um eine ERHALTEN anfordern. Sie erwarten eine Antwort mit dem Statuscode von 200. Dann erwarten Sie, dass die ToDos-Länge 2 beträgt.

Wenn Sie den Test ausführen, sollten Sie eine Fehlermeldung erhalten. Versuchen Sie, den Fehler auf eigene Faust weiterzugeben.

Ich wette, du hast das zum Laufen bekommen. Hier ist der Code, um den Test bestehen zu lassen; Vergleichen Sie es mit Ihrer Lösung.

# server / server.js app.get ('/ todos', (req, res) => Todo.find (). dann ((todos) => res.send (todos), (e) => res.status (400) .send (e)))

Wenn ein ERHALTEN Anfrage wird an die gestellt / todos Sie möchten alle Aufgaben in der Todo-Sammlung finden und als Aufgaben zurückgeben. Hinzufügen zu server.js bewirkt, dass der Test bestanden wird.

Als Nächstes schreiben Sie drei Tests für die ERHALTEN Aufforderung zum Abrufen einzelner Aufgaben. Der erste sollte die Aufgaben abrufen und zurückgeben. Die zweite und dritte sollte zurückkehren 404 Fehler in Fällen, in denen die Aufgabe nicht gefunden wurde.

Öffne deine server.test.js und erstellen Sie einen neuen Beschreibungsblock mit dem ersten Testfall.

# server / server.test.js beschreiben ('GET / todos /: id', () => es ('sollte todo doc zurückgeben', (done) => request (app) .get ('/ todos / $ todos [0] ._ id.toHexString () ') .expect (200) .expect ((res) => expect (res.body.todo.text) .toBe (todos [0] .text) ) .end (erledigt))

Dieser Test macht ein ERHALTEN anfordern, um die ersten in Ihrer Datenbank verfügbaren Aufgaben abzurufen. Sie erwarten eine 200 Statuscode und prüfen Sie dann, ob der Textwert der Aufgabe mit dem erstellten übereinstimmt.

Der nächste Test sieht so aus.

 it ('sollte 404 zurückgeben, wenn keine Aufgabe gefunden wurde', (done) => let _id = new ObjectId ('5967989ee978311656e93a59') request (app) .get ('/ todos / $ todos / _id.toHexString ()) ') .expect (404) .end (done))

Hier suchen Sie nach einer Aufgabe, die eine ID verwendet, die nicht der ID der in Ihrer Datenbank gespeicherten Aufgaben entspricht. Der Test erwartet, dass diese Anforderung a zurückgibt 404 Error.

Der letzte Test ist wie der erste, aber etwas anders. So sieht es aus.

 it ('sollte 404 für Nicht-Objekt-IDs zurückgeben', (done) => let hexId = '5967989ee978311656e93a5312' request (app) .get ('/ todos / $ todos / hexId') .expect (404). Ende (erledigt)))

Hier erstellen Sie eine ungültige Objekt Identifikation und versuchen Sie, die Datenbank abzufragen, um eine entsprechende Aufgabe zu erhalten Objekt Identifikation erstellt. Der Test erwartet, dass die Anfrage a zurückgibt 404 Error. 

Wenn Sie den Test ausführen, sollten alle fehlschlagen. Um sie zu übergeben, fügen Sie den folgenden Code zu Ihrem hinzu server.js Datei.

# server / server.js app.get ('/ todos /: id', (req, res) => let id = req.params.id // 1 if (! ObjectId.isValid (id)) // 2 return res.status (404) .send ('ID ist ungültig') Todo.findById (id) .then ((todo) => if (! Todo) // 3 return res.status (404) .send () res.send (todo) // 4). catch ((e) => res.status (400) .send ()))
  1. Rufen Sie die ID der aus den Parametern angeforderten Aufgaben ab.
  2. Prüfen Sie, ob die ID gültig ist. Wenn die ID nicht gültig ist, wird ein Fehler gesendet, der dies angibt.
  3. Wenn die ID gültig ist, versuchen Sie, mithilfe der Option eine Aufgabe zu finden, die dieser ID entspricht findById Methode. Wenn mit dieser ID keine Aufgabe gefunden wird, a 404 Fehler wird gesendet.
  4. Wenn eine Aufgabe gefunden wird, wird die Aufgabe gesendet. Dann fangen Sie jeden Fehler ab und senden ihn.

Führen Sie den Testbefehl noch einmal aus und er sollte bestehen.

DELETE Request Test

Der Test für Ihre LÖSCHEN Anfrage wird ein bisschen wie das, was Sie für Ihre GET-Anfrage haben.

Zunächst möchten Sie testen, ob eine Aufgabe gelöscht wird.

# server / test / server.test.js beschreiben ('DELETE / todos /: id', () => it ('sollte ein todo löschen', (done) => let hexId = todos [0] ._ id .toHexString () // 1 request (app) .delete ('/ todos / $ hexId') .expect (200) .expect ((res) => expect (res.body.todo._id) .toBe (hexId)) .end ((err, res) => // 2 if (err) return done (err)) Todo.findById (hexId) .then ((todo) => // 3 erwart (todo.hexId) .toNotExist () done ()). catch ((e) => done (e)))

Folgendes passiert oben:

  1. Sie setzen die ID der Aufgabe auf eine Variable, die aufgerufen wird hexId. Als nächstes a LÖSCHEN Die Anforderung wird unter Verwendung der ID an den Pfad der Aufgabe gestellt. Sie erwarten eine 200 Antwort und die To-Do erhalten, um den Wert von hexId.
  2. Wenn ein Fehler auftritt, wird er zurückgegeben.
  3. Wenn kein Fehler vorliegt, fragt der Test Ihre Datenbank mit der als Wert von gespeicherten ID ab hexId. Seit einem LÖSCHEN Anfrage wurde bereits gesendet, erwartet der Test, dass die mit dieser ID übereinstimmende Aufgabe nicht vorhanden ist.

Als Nächstes möchten Sie testen, dass beim Löschen einer Aufgabe, die nicht vorhanden ist, die Antwort eine Antwort enthält 404 Error. Dies ist wichtig, da ein zweimaliges Löschen einer Aufgabe nicht möglich ist. So sollte der Test dafür aussehen.

# server / test / server.test.js it ('sollte 404 zurückgeben, wenn todo nicht gefunden wird', (done) => let hexId = new ObjectId (). toHexString () request (app) .delete ('/ todos / $ todos / hexId ') .expect (404) .end (done))

Dadurch wird eine ID für eine Aufgabe erstellt, die in der Datenbank nicht vorhanden ist. Dann ein LÖSCHEN Es wird angefordert, die Aufgabe zu löschen. Es wird erwartet, dass der Test a zurückgibt 404 Fehler, da die Aufgabe nicht existiert.

Sie möchten das testen LÖSCHEN Bei Verwendung einer ungültigen ID wird a 404 Fehler wie so.

# server / test / server.test.js es ('sollte 404 für Nicht-Objekt-IDs zurückgeben'), (done) => request (app) .delete ('/ todos / 123abc') .expect (404) .end (erledigt) ) )

Um den Test zu bestehen, öffnen Sie Ihre server.js und legen Sie diese ab.

# server / server.js app.delete ('/ todos /: id', (req, res) => let id = req.params.id if (! 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 ()))

Führen Sie den Befehl zum Testen aus:

npm run test

Und deine Tests sollten bestanden sein.

Fazit

An diesem Punkt wissen Sie jetzt, wie Sie eine Testsuite einrichten, wenn Sie eine API mit Node.js erstellen. Sie haben Mocha, Expect und Supertest verwendet, um eine API zu testen. Ein Vorteil dabei ist, dass Sie beim Erstellen Ihrer API nicht immer Postman starten müssen. Mit Ihrem Test können Sie herausfinden, was kaputt ist.

Beachten Sie vor dem Abschluss, dass JavaScript zu einer der De-facto-Sprachen der Web-Arbeit geworden ist. Es ist nicht ohne Lernkurven, und es gibt viele Frameworks und Bibliotheken, um Sie zu beschäftigen. Wenn Sie nach zusätzlichen Ressourcen suchen, um zu studieren oder in Ihrer Arbeit zu verwenden, informieren Sie sich über das Angebot von Envato Market.

Mit dem, was Sie jetzt wissen, können Sie die Welt des Testens erkunden.