Εντάξει! έχουμε το περιβάλλον μας έτοιμο και τρέχει, οπότε… ας εφαρμόσουμε έναν διακομιστή REST API που βασίζεται στο NodeJS. Μια σύντομη ανακεφαλαίωση:

  • Το αποθετήριο μας φιλοξενείται στο GitHub και θα χρησιμοποιήσουμε το GitKraken για τη διαχείριση του τοπικού και απομακρυσμένου αποθετηρίου μας.
  • Θα αναπτύξουμε χρησιμοποιώντας τον κώδικα του Visual Studio.
  • Έχουμε την πιο πρόσφατη έκδοση NodeJS εγκατεστημένη στον υπολογιστή μας.

Μερικοί άνθρωποι πρέπει να διαβάσουν πολλή τεκμηρίωση πριν να εφαρμόσουν το πρώτο τους "Hello world". Δεν μου αρέσουν τα παραδείγματα "Hello Worlds" γιατί μερικές φορές είναι χάσιμο χρόνου. Προτιμώ να είμαι γενναίος και να αρχίσω να κωδικοποιώ απευθείας, αν και δεν έχω ιδέα για τη γλώσσα.

Ο καλύτερος τρόπος για να μάθετε να προγραμματίζετε είναι μέσω προγραμματισμού.

Περίληψη.

  1. Δομή έργου: παρακαλώ, να είστε τακτοποιημένοι (όσο το δυνατόν περισσότερο).
  2. Hello World: Εντάξει, είναι απλώς ένα αστείο. Τρέχω το πρώτο μου σενάριο.
  3. Συνταγή: στοιχεία για τη δημιουργία ενός REST API.
  4. Μην είστε τεμπέλης, παρακαλώ: Δοκιμάστε τον κωδικό σας!
  5. Καθαρός κώδικας: χρησιμοποιήστε την κοινή λογική σας.

Πώς να δομήσετε το έργο διακομιστή σας.

Έχουμε έναν κενό φάκελο μέχρι εδώ. Λέω ψέματα, αν έχουμε δημιουργήσει ένα αποθετήριο στο GitHub, θα πρέπει να έχουμε τουλάχιστον ένα αρχείο README. Τέλος πάντων, πρώτο βήμα: κλωνοποιήστε το αποθετήριοστον υπολογιστή σας για να εργαστείτε με ένα τοπικό αποθετήριο. Ωραία, έχετε τώρα ένα αντίγραφο του απομακρυσμένου αποθετηρίου σας στον υπολογιστή σας. Παρακαλώ, δημιουργήστε τώρα ένα νέο υποκατάστημα, δεν θέλουμε να εργαστούμε κάτω από τον κύριο κλάδο (εάν το γαμήσετε, είναι καλύτερο να διαγράψετε οποιοδήποτε κλάδο παρά να διαγράψετε τον κύριο κλάδο…).

Συγχαρητήρια! Είμαστε έτοιμοι να σκεφτούμε τη δομή μας. Μην πανικοβάλλεστε! Όταν μιλάμε για τη δομή του έργου, αναφέρεται ο τρόπος με τον οποίο πρόκειται να οργανώσουμε τα αρχεία προέλευσης σε φακέλους με τέτοιο τρόπο ώστε να μπορούμε να έχουμε τα αρχεία εύκολα διαθέσιμα, ομαδοποιημένα κατά λειτουργικότητα και εύκολο χειρισμό. Όπως πρόκειται να αναπτύξουμε με JavaScript, ο εύκολος τρόπος είναι να έχουμε μόνο ένα αρχείο με όλο τον πηγαίο κώδικα, αλλά αυτή είναι μια πολύ κακή πρακτική.

Διαίρει και βασίλευε! Εάν ο κώδικάς μας έχει σφάλματα, είναι εύκολο να τα διορθώσουμε αν χωρίσουμε τη λειτουργικότητά μας σε διαφορετικά αρχεία. Επίσης, αυτός ο κώδικας είναι πιο εύκολος στον εντοπισμό σφαλμάτων.

Θυμηθείτε, πρόκειται να αναπτύξουμε έναν διακομιστή REST API, οπότε ας δημιουργήσουμε μερικούς φακέλους στον τοπικό μας φάκελο αποθετηρίου:

  • src: αυτός ο φάκελος θα αποθηκεύσει όλο τον πηγαίο κώδικα μας. Με τη σειρά του, θα έχει περισσότερους υποφακέλους. Επειδή ο διακομιστής μας είναι REST API, θα μετονομάσω αυτόν τον φάκελο σε api.
  • έγγραφο: θα τοποθετήσουμε την τεκμηρίωσή μας σε αυτόν τον φάκελο. Διαγράμματα, ροές, απαιτήσεις κ.λπ.
  • δοκιμές: ένας ειδικός φάκελος για τις δοκιμές μονάδων μας. Ορισμένοι συγγραφείς περιλαμβάνουν το αρχείο δοκιμής μονάδας στο ίδιο επίπεδο με τον πηγαίο κώδικα. Δεν μου αρέσει αυτή η προσέγγιση γιατί αν χρειαστεί να διανείμετε το λογισμικό σας, είναι πιο εύκολο να παραλείψετε έναν φάκελο.
  • config: εάν χρειαζόμαστε κάποια επιπλέον διαμόρφωση για την υλοποίησή μας, αυτό είναι το σωστό μέρος (για παράδειγμα, για να διαμορφώσουμε μια βάση δεδομένων ή άλλα API τρίτων).

Νομίζω ότι είναι αρκετό με αυτούς τους φακέλους… Τώρα, αρχικοποιήστε το έργο σας με npm init για να δημιουργήσετε ένα package.json και δημιουργήστε ένα αρχείο index.js.

ΣΗΜΕΙΩΣΗ: Δημιουργώ το έργο από την αρχή, επομένως θα χρησιμοποιήσω καθαρά JavaScript προς το παρόν.

Ωραία, θα πρέπει να έχετε έναν φάκελο όπως αυτός:

Τελικά! Η ώρα του κώδικα!

Ας δημιουργήσουμε λίγο κώδικα και ας δούμε πώς να τρέξουμε έναν διακομιστή με JavaScript και NodeJS. Ενημερώστε το index.js σας και συμπεριλάβετε τον ακόλουθο κώδικα:

Εύκολο, σωστά; Λοιπόν, αν θέλετε να δοκιμάσετε τον κωδικό σας, έχετε 2 τρόπους για να το κάνετε:

  • Ανοίξτε ένα τερματικό και μεταβείτε στον κατάλογο όπου βρίσκεται το αρχείο index.js.
  • Ανοίξτε το τερματικό στον κώδικα του Visual Studio και θα τοποθετηθεί απευθείας στον κατάλογο όπου βρίσκονται το index.js σας.

Τώρα, πληκτρολογήστε στο τερματικό σας:

node index.js

Αυτή η εντολή θα εκτελέσει το σενάριό σας και θα δείτε το μήνυμα Διακομιστής που εκτελείται στη θύρα 4200. Εξαιρετική! Έχετε εκτελέσει το πρώτο σας σενάριο στο NodeJS! Τώρα, δοκιμάστε να συνδεθείτε στο http://localhost:4200 και δείτε τι συμβαίνει. Εάν χρησιμοποιείτε ένα πρόγραμμα περιήγησης για πρόσβαση σε αυτό το URL, ίσως δεν θα δείτε τίποτα ενδιαφέρον. Επομένως, δοκιμάστε να χρησιμοποιήσετε το Postman που είναι ένα ισχυρό εργαλείο για την κατανάλωση REST API και ελέγξτε εάν ο κώδικάς σας λειτουργεί σωστά. Ας εξηγήσουμε λίγο τον κώδικα:

const http = require("http");

Αυτή η πρόταση μας επιτρέπει να χρησιμοποιήσουμε τη μονάδα HTTP στον κώδικά μας. Το HTTP είναι μια ενσωματωμένη λειτουργική μονάδα NodeJS, που σημαίνει όταν πρέπει να χρησιμοποιήσουμε μια ενσωματωμένη λειτουργική μονάδα NodeJS (υπάρχουν πολλά, θα μιλήσω για αυτά αργότερα) ή όταν πρέπει να χρησιμοποιήσουμε μια εξωτερική μονάδα στον κώδικά μας, χρησιμοποιούμε την ανάγκη για εισαγωγή αυτής της ενότητας/βιβλιοθήκης στον κώδικά μας.

let app = http.createServer((req, res) => {
   res.writeHead(200, {'Content-Type': 'application/json'})
   res.end();
});

Το επόμενο κομμάτι κώδικα δείχνει πώς να δημιουργήσετε έναν διακομιστή με τη λειτουργική μονάδα NodeJS HTTP. Αρχικά, πρέπει να χρησιμοποιήσουμε τη συνάρτηση createServer() η οποία λαμβάνει μια επιστροφή κλήσης ως όρισμα. Αυτή η επανάκληση είναι μια συνάρτηση με δύο ορίσματα, το reqκαι το res, που αντιπροσωπεύει τα αιτήματα και τις απαντήσεις προς/από τον διακομιστή. Όπως μπορείτε να δείτε, δεν χρησιμοποιώ την τυπική συνάρτηση JavaScript ως όρισμα της συνάρτησης createServer. Αντίθετα, χρησιμοποιώ μια συνάρτηση βέλους. Ο σκοπός αυτής της επανάκλησης είναι να στέλνει μια απάντηση κάθε φορά που ένας διακομιστής λαμβάνει ένα αίτημα λόγω του ότι είναι ακροατής αιτήματος.

Τι κάνουν το req (αίτημα) και το res(απάντηση); Και οι δύο είναι ροές, το αντικείμενο αιτήματος είναι μια αναγνώσιμη ροή και η απάντηση είναι μια ροή με δυνατότητα εγγραφής, έτσι μπορείτε να χρησιμοποιήσετε αίτημα για ανάγνωση ενός σώματος που στέλνει ένας πελάτης στον διακομιστή και απάντηση για να γράψετε αυτό που θέλετε να επιστρέψετε στους πελάτες . Στο κομμάτι του κώδικα μας, γράφουμε μια κεφαλίδα με έναν κωδικό κατάστασης και, στη συνέχεια, τελειώνουμε την επικοινωνία.

app.listen(port, () => {
    console.log(`Server running on port ${port}`);
});

Το τελευταίο μέρος του κώδικα λέει στον διακομιστή σε ποια θύρα πρέπει να ακούει και εκτυπώνει ένα μήνυμα όταν ο διακομιστής είναι έτοιμος να λάβει αιτήματα.

REST API υπό κατασκευή.

Τι χρειαζόμαστε για να δημιουργήσουμε ένα REST API; Το NodeJS μας προσφέρει πολλές δυνατότητες να δημιουργήσουμε διακομιστές, αλλά πρέπει να τους εφαρμόσουμε όλους μόνοι μας… έτσι, για να δημιουργήσουμε ένα REST API το συντομότερο δυνατό, αυτό χρειάζομαι:

  • Express: Βασικά, είναι ένα πλαίσιο για το NodeJS που μας επιτρέπει να κατασκευάζουμε REST API γρήγορα και εύκολα.
  • Swagger: Μας επιτρέπει να σχεδιάζουμε, να κατασκευάζουμε, να τεκμηριώνουμε, να δοκιμάζουμε και να τυποποιούμε εύκολα το API μας. Θα χρησιμοποιήσουμε ένα αρχείο που ονομάζεται swagger.yaml για να διαμορφώσουμε όλες τις διαδρομές API μας, καθώς και για να τεκμηριώσουμε καθεμία από αυτές.

Η Express αναλαμβάνει δράση!

Ας μετατρέψουμε τον κώδικά μας για χρήση Express.

Καμία διαφορά; Αντικαταστήσαμε τη λειτουργική μονάδα HTTP από την ενότητα express. Στη συνέχεια, δημιουργήσαμε την εφαρμογή express μας και είπαμε στη express ότι θέλουμε να καταγράψουμε όλα τα αιτήματα που γίνονται στο "/" (στην πραγματικότητα, πρέπει να ζητήσουμε στο "http://localhost:4200/)." Η ακόλουθη γραμμή κώδικα είναι πώς μπορούμε να διαμορφώσουμε ποιες διαδρομές θέλουμε να εκθέσουμε στο API μας.

app.get("/", (req, res) => res.send("this is your response"));

Η συνάρτηση app.get() αντιπροσωπεύει μια λειτουργία HTTP GET, επομένως εάν πρέπει να υποβάλουμε ένα αίτημα στον διακομιστή μας, θα πρέπει να χρησιμοποιήσουμε το GET, διαφορετικά, ο διακομιστής μας θα απαντήσει με σφάλμα.

Απλά μια υπενθύμιση, το express δεν περιλαμβάνεται στις ενσωματωμένες μονάδες NodeJS, επομένως πρέπει να εγκαταστήσουμε την εξάρτηση με npm.

npm install --save express

Περίμενε! Τι γίνεται με τον Swagger;

Μέχρι στιγμής ήταν πολύ, πολύ εύκολο, αλλά θέλουμε να το κάνουμε πιο εύκολο. Τι χρειαζόμαστε λοιπόν; Απλώς Swagger. Μην προσπαθήσετε να διαβάσετε ολόκληρη την τεκμηρίωση γιατί είναι επίσης… πώς να το πω… καλά, δεν πειράζει. Εδώ έχουμε την προδιαγραφή. Ας αλλάξουμε τον κωδικό άλλη μια φορά.

Όπως μπορείτε να δείτε, χρειαζόμαστε μια νέα εξάρτηση, επομένως πρέπει να την εγκαταστήσουμε πρώτα. Στη συνέχεια, δημιουργούμε τη διαμόρφωση αυτού του ενδιάμεσου λογισμικού, και τέλος καταχωρούμε την εφαρμογή express. Με αυτό το κομμάτι κώδικα, δεν χρειάζεται να προσθέσουμε τίποτα άλλο στο αρχείο μας index.js προς το παρόν.

Οι προδιαγραφές του API μας θα οριστούν σε ένα αρχείο που ονομάζεται swagger.yaml. Θα περιγράφει όλες τις διαδρομές μας που εκτίθενται από το API καθώς και τους ελεγκτές JavaScript που θα εκτελούν τον κώδικά μας.

Πρέπει να εγκαταστήσουμε την εξάρτηση ενδιάμεσου λογισμικού για να τρέξουμε τον κώδικά μας:

npm install --save swagger-express-mw

Αφού ορίσουμε το αρχείο μας swagger.yaml, πρέπει να προσθέσουμε ένα τελικό αρχείο στη δομή του έργου μας κάτω από το φάκελο api/controllers με τον κωδικό κάθε λειτουργίας που χρειαζόμαστε για τον ελεγκτή που καθορίζεται στο στοιχείο επέκτασης x-swagger-router-controller. Το όνομα του ελεγκτή JavaScript θα πρέπει να είναι το ίδιο με αυτό που καθορίζεται στο στοιχείο επέκτασης.

Πρέπει να εξαγάγουμε τη συνάρτηση που αντιπροσωπεύει μια λειτουργία έχοντας κατά νου ότι θα πρέπει να έχει το ίδιο όνομα με το στοιχείο operationId μέσα στο swagger.yaml διαμόρφωση.

Να είστε προσεκτικοί με την εσοχή του αρχείου swagger.yaml. Θα πρέπει να το προσέξετε γιατί αν υπάρχουν στοιχεία με κακή αναγνώριση, τότε η εφαρμογή μας δεν θα εκτελεστεί και θα εμφανιστεί ένα σφάλμα.

Ο υπέροχος κόσμος των Unit Tests.

Έχω εξαπατήσει ενώ ανέπτυζα τον διακομιστή REST API… Θα έπρεπε να είχα δοκιμάσει την εφαρμογή μου ενώ ανέπτυζα τη λειτουργικότητα 😔… Αλλά δεν είναι πολύ αργά ακόμα.

Γνωρίζω ότι ως φοιτητής αυτό είναι το χειρότερο μέρος του να είσαι προγραμματιστής, αλλά όταν εργάζεσαι σε μια εταιρεία, θα δεις ότι η δοκιμή μονάδας είναι εξαιρετικά σημαντική. Όπως γνωρίζετε, είναι πολύ χρήσιμα για τον εντοπισμό όσο το δυνατόν περισσότερων ζητημάτων κατά τη φάση ανάπτυξής μας, έχοντας κατά νου ότι αναπτύσσουμε μια εφαρμογή JavaScript. Η JavaScript είναι μια ισχυρή δυναμική γλώσσα, αλλά η επιλογή της JavaScript φέρει μεγάλη ευθύνη. Επομένως, πρέπει να φροντίσουμε για σφάλματα χρόνου εκτέλεσης και μεταγλώττισης αναπτύσσοντας χρήσιμες δοκιμές μονάδων.

Είναι καλή πρακτική να αναπτύσσουμε τις δοκιμές μονάδας την ίδια στιγμή που αναπτύσσουμε τη λειτουργικότητά μας ακολουθώντας μία από αυτές τις αρχές: TDD ή BDD.

Είμαι συνηθισμένος στο TDD ή στο Test Driven Development, οπότε θα ακολουθήσω αυτήν την αρχή. Ας υποθέσουμε ότι θέλουμε να εφαρμόσουμε μια συνάρτηση JavaScript που προσθέτει δύο αριθμούς. Αυτή είναι η ίδια η λειτουργία:

function add(a, b) {
    return a + b;
}
exports.add = add;

Είναι μια απλή συνάρτηση, το ξέρω, αλλά ας υποθέσουμε ότι δεν ξέρουμε τι να κάνουμε μέσα στη συνάρτηση. Ακολουθώντας την αρχή TDD, πρώτα πρέπει να αναπτύξω μια δοκιμή μονάδας που αποτυγχάνει. Μην δίνετε σημασία στον κώδικα τουλάχιστον προς το παρόν, γιατί θα τον εξηγήσω αργότερα.

// Im'm requiring a file that has a function exported,
// not the add function itself
const add = require("add");
describe("add test suit", () => {
   it("adds two integer numbers", () => {
      expect(add()).toEqual(0);
   });
});

Αυτό το κομμάτι του κώδικα δοκιμής μονάδας αποτυγχάνει επειδή καλώ μια συνάρτηση που δεν υπάρχει ήδη, επομένως το επόμενο βήμα είναι να αναπτύξετε τη συνάρτηση add() σε ένα αρχείο που ονομάζεται add.js που εξάγει την προαναφερθείσα συνάρτηση:

function add() {
   return 0;
}
exports.add = add;

Τώρα, η προηγούμενη δοκιμή λειτουργεί, επομένως, καθώς δεν έχω ολοκληρώσει την πραγματική συμπεριφορά της συνάρτησης (θυμηθείτε, θα πρέπει να προσθέσει δύο αριθμούς), πρέπει να ενημερώσω τη δοκιμή για να αποτύχει ξανά:

// Im'm requiring a file that has a function exported,
// not the add function itself
const add = require("add");
describe("add test suit", () => {
   it("adds two integer numbers", () => {
      const a = 1;
      const b = 2;
      expect(add(a, b)).toEqual(a + b);
   });
});

Η δοκιμή αποτυγχάνει ξανά επειδή η συνάρτηση επιστρέφει 0 και της δίνω δύο ορίσματα. Στη συνέχεια, ας ενημερώσουμε τη συνάρτηση:

function add(a, b) {
   return a + b;
}
exports.add = add;

Τέλεια, η λειτουργία ολοκληρώθηκε και η δοκιμή λειτουργεί! Έχω τη λειτουργία μου έτοιμη για περιβάλλον παραγωγής. Συνοψίζοντας, αν θέλουμε να εφαρμόσουμε το TDD πρέπει:

  1. Δημιουργήστε μια δοκιμή μονάδας που αποτυγχάνει.
  2. Δημιουργήστε έναν κωδικό που κάνει τη δοκιμή μονάδας να λειτουργεί.
  3. Ενημερώστε τη δοκιμή μονάδας για να αποτύχει ξανά.
  4. Ενημερώστε τον κωδικό για να λειτουργήσει η δοκιμή μονάδας.
  5. Επαναλάβετε τα βήματα 3-4 μέχρι να ολοκληρώσουμε όλη την αναμενόμενη συμπεριφορά.

Ποιο πλαίσιο πρέπει να επιλέξω για να δοκιμάσω μια εφαρμογή NodeJS;

Υπάρχουν πολλά πλαίσια που μπορούμε να επιλέξουμε όταν αναπτύσσουμε μια εφαρμογή NodeJS. Εδώ έχουμε μερικά από τα πιο δημοφιλή:

  • Jasmine: Νομίζω ότι είναι τα πιο εύκολα δοκιμαστικά πλαίσια για αρχάριους. Μπορούμε να δημιουργήσουμε δοκιμές μονάδων και ολοκλήρωσης για JavaScript και περιλαμβάνει τη λειτουργία ισχυρισμών καθώς και μια καλή δομή δοκιμών. Μπορεί να δημιουργήσει αποτελέσματα δοκιμών που πέρασαν/απέτυχαν και μπορούμε να κοροϊδέψουμε τη λειτουργικότητα χωρίς βιβλιοθήκες τρίτων. Αυτό είναι το πλαίσιο που προτιμώ.
  • Mocha: Είναι παρόμοιο με το Jasmine, αλλά δεν έχω δουλέψει ποτέ με μόκα. Ρίξτε μια ματιά και μη διστάσετε να διαλέξετε ό,τι προτιμάτε.
  • Jest: Έχω δουλέψει με το Jest σε μια εφαρμογή NodeJS που δημιουργήθηκε με τη χρήση TypeScript. Δεν είναι περίπλοκο, αλλά δεν λειτούργησε όπως περίμενα. Το Jest είναι ως επί το πλείστον συμβατό με το Jasmine, επομένως θα μπορούσατε να μεταφέρετε εύκολα από το Jasmine στο Jest, και υποτίθεται ότι είναι πιο ισχυρό και με καλύτερη απόδοση. Δεν είδα κανένα από αυτά τα χαρακτηριστικά.

Τι πρέπει να γνωρίζετε για τη Jasmine;

Πρώτα, πρέπει να μάθετε τι είναι μια δοκιμαστική στολή. Σκοπός του είναι να ομαδοποιήσει μεμονωμένα τεστ που σχετίζονται μεταξύ τους. Για παράδειγμα, εάν θέλουμε να δοκιμάσουμε μια τάξη με διαφορετικές μεθόδους ή ένα αρχείο με διαφορετικές συναρτήσεις, μια δοκιμαστική φόρμα θα είναι η κλάση ή το αρχείο. Στο Jasmine θα δημιουργήσουμε μια δοκιμαστική στολή χρησιμοποιώντας τη μέθοδο describe():

describe("name of your test suit", () => {});

Αυτή η μέθοδος λαμβάνει δύο ορίσματα, μια συμβολοσειρά που αντιπροσωπεύει το όνομα της δοκιμαστικής φόρμας και μια συνάρτηση επανάκλησης με τον κώδικα να εκτελείται για κάθε δοκιμαστική φόρμα. Μπορούμε να φωλιάζουμε όσες δοκιμαστικές σουίτες χρειαζόμαστε, αν και είναι καλή πρακτική να έχουμε μόνο δύο επίπεδα φωλιάς.

Η επόμενη ιδέα που πρέπει να γνωρίζετε είναι τι αντιπροσωπεύει ένα μόνο τεστ. Κάθε συνάρτηση describe() θα πρέπει να συμπληρώνεται με πολλές συναρτήσεις it(). Μια συνάρτηση it() είναι μια δοκιμή απομονωμένης μονάδας.

it("name of the isolated, standalone test", () => {});

Είναι σημαντικό να μην δημιουργείτε εξαρτήσεις μεταξύ κάθε συνάρτησης it(). Δεν πρέπει να χρησιμοποιούμε το αποτέλεσμα μιας συνάρτησης it() σε άλλες συναρτήσεις it(). Αυτό σημαίνει ότι κάθε συνάρτηση it() θα πρέπει να είναι αυτόνομη.

Άλλες λειτουργίες του Jasmine που πρέπει να έχουμε κατά νου είναι:

  • beforeEach(): Αυτή η συνάρτηση είναι χρήσιμη για τη διαμόρφωση κώδικα που πρέπει να εκτελείται πριν από κάθε συνάρτηση it(). Λαμβάνει μια συνάρτηση επανάκλησης ως όρισμα.
  • beforeAll(): Λειτουργεί με παρόμοιο τρόπο όπως πριν από τοEach, αλλά θα εκτελεστεί μόνο μία φορά σε κάθε describe() συνάρτηση.
  • AfterEach(): Το ίδιο με το beforeEach() αλλά εκτελείται μετά από κάθε συνάρτηση it().
  • AfterAll(): Θα εκτελεστεί μία φορά μετά από μια συνάρτηση describe().

Τέλος, θα πρέπει να γνωρίζουμε ποιες λειτουργίες διεκδίκησης προσφέρει το Jasmine:

  • expect(actual): το πραγματικό όρισμα είναι η τιμή ενός αντικειμένου που θέλουμε να συγκρίνουμε μετά την εκτέλεση της δοκιμής.
  • toBe(αναμενόμενο): αυτή η συνάρτηση συγκρίνει την πραγματική τιμή με την αναμενόμενη τιμή. Αποτυγχάνει εάν η πραγματική και η αναμενόμενη τιμή δεν είναι ίση. Αυτή η συνάρτηση απλώς συγκρίνει πρωτόγονους τύπους (αριθμούς, συμβολοσειρές, booleans…).
  • toEqual(αναμενόμενο): Είναι το ίδιο με τη λειτουργία toBe() αλλά συγκρίνει αντικείμενα.

Εφαρμογή δοκιμών μονάδας στον διακομιστή REST API.

Πρώτα, πρέπει να εγκαταστήσω την εξάρτηση Jasmine:

npm install --save-dev jasmine

Όπως μπορείτε να δείτε, χρησιμοποιώ -.-save-dev ως επιλογή. Με αυτήν την επιλογή, λέω στο npm ότι πρόκειται να χρησιμοποιήσω αυτήν την εξάρτηση μόνο με σκοπό ανάπτυξης, επομένως δεν θα προστεθεί σε μια διανομή παραγωγής. Αφού εγκατασταθεί, πρέπει να δημιουργήσουμε ένα αρχείο διαμόρφωσης jasmine που ονομάζεται jasmine.json:

Για να εκτελούμε εύκολα τις δοκιμές μας, πρόκειται να διαμορφώσω μια δοκιμαστική εντολή στο αρχείο μας package.json:

Δείτε την ενότητα σενάρια. Μπορώ να εκτελέσω όλες τις δοκιμές στον φάκελο testsμε την καθορισμένη διαμόρφωση και χρειάζομαι απλώς μια εντολή:

npm test

Τέλος, μπορώ να αναπτύξω τις δοκιμές μονάδας μου. Για παράδειγμα, θα σας δείξω τη δοκιμή μονάδας του ελεγκτή home.js.

Αυτό το σενάριο είναι μια δοκιμαστική φόρμα του ελεγκτή, επομένως το πρώτο describe() αναφέρεται στο όνομα του τελικού σημείου που θέλω να δοκιμάσω και είναι το ίδιο που είχα ρυθμίσει προηγουμένως στο αρχείο swagger.yaml "/api". Αυτό το τελικό σημείο έχει απλώς μια λειτουργία λήψης, αλλά θα μπορούσε να έχει και άλλες, όπως ανάρτηση, τοποθέτηση ή διαγραφή, αυτός είναι ο λόγος για τον οποίο έχω ενσωματώσει μια άλλη συνάρτηση describe() με το όνομα της επέμβασης που δοκιμάζω.

Θυμηθείτε την υλοποίηση του ελεγκτή home.js. Εξάγει μια συνάρτηση που απαιτεί δύο ορίσματα, ένα αίτημα και μια απάντηση. Για να δοκιμάσω αυτήν τη συνάρτηση, πρέπει να δημιουργήσω ψεύτικα αντικείμενα αιτήματος και απόκρισης επειδή είναι αντικείμενα που δεν έχω ορίσει στον κώδικά μου. Ο τρόπος με τον οποίο μπορούμε να δημιουργήσουμε ψεύτικα ή χλευασμένα αντικείμενα στο Jasmine είναι η συνάρτηση createSpyObj(). Αυτή η συνάρτηση δημιουργεί ένα αντικείμενο με ψεύτικες συναρτήσεις που κάνουν οτιδήποτε. Δώστε προσοχή στον ελεγκτή home.js:

res.status(200).end();

Χρησιμοποιούμε το αντικείμενο απόκρισης (res) για να στείλουμε μια κατάσταση στον πελάτη και να τερματίσουμε την επικοινωνία. Όπως μπορείτε να δείτε, αλυσιδώνουμε τις κλήσεις σε μία μόνο πρόταση, και αυτό σημαίνει ότι η συνάρτηση status() επιστρέφει ένα αντικείμενο με τον ίδιο τύπο του αντικειμένου res. Αυτός είναι ο λόγος για τον οποίο δημιουργώ μια ψεύτικη κλήση στη μέθοδο status() στον κώδικα δοκιμής.

resMock.status.and.callFake(() => {
   return resMock;
});

Όταν εκτελείται η δοκιμή, πριν από κάθε συνάρτηση it() δημιουργώ μια ψεύτικη κλήση του status() λειτουργία που επιστρέφει το ίδιο το αντικείμενο resMock. Όπως είπα πριν, το createSpyObj() δημιουργεί ψεύτικες συναρτήσεις, αλλά δεν ξέρουν τι να κάνουν ή τι πρέπει να επιστρέψουν και αυτός είναι ο λόγος που δημιουργώ αυτή την ψεύτικη κλήση. Στη συνέχεια, εκτελείται ο κώδικας της συνάρτησης it(), καλώντας την εξαγόμενη συνάρτηση του ελεγκτή home.js. Θέλουμε να ελέγξουμε εάν μετά την κλήση της εξαγόμενης συνάρτησης, επιστρέφει μια απόκριση 200 ΟΚ στους πελάτες.

expect(resMock.status).toHaveBeenCalledWith(200);

Αυτό το κομμάτι κώδικα αναμένει ότι η συνάρτηση resMock.status έχει κληθεί με όρισμα ίσο με 200. Το δοκιμαστικό πέρασμα επειδή το home.js ο ελεγκτής αποκρίνεται με κατάσταση 200 OK.

Συμβουλές και κόλπα: διατηρήστε τον κωδικό σας καθαρό.

Υπάρχει πολλή τεκμηρίωση σχετικά με τον καθαρό κώδικα, επομένως θα μπορούσε να είναι ενδιαφέρον να ρίξετε μια ματιά στο Διαδίκτυο για να καταλάβετε τι είναι καθαρός κώδικας. Σε ορισμένες εταιρείες, οι προγραμματιστές ακολουθούν οδηγούς καθαρού κώδικα που παρέχονται από την ίδια την εταιρεία. Καθώς πιθανότατα είστε μαθητής, μπορείτε να ξεκινήσετε να διαβάζετε ένα ενδιαφέρον βιβλίο: The Clean Code του Robert C. Martin.

Για να μην επεκτείνουμε άσκοπα αυτή την ιστορία, εδώ έχετε μια ενδιαφέρουσα ανακεφαλαίωση.

Είναι πολύ σημαντικό να ακολουθείτε τους οδηγούς καθαρού κώδικα προκειμένου να εφαρμόσετε έναν ευανάγνωστο, διατηρήσιμο και επεκτάσιμο κώδικα. Είναι σημαντικό να μπορείτε να διαβάσετε τον δικό σας κώδικα, αλλά είναι ακόμα πιο σημαντικό να μπορούν να τον διαβάσουν και άλλοι.

Και κάπως έτσι τελειώνει αυτή η ιστορία. Εάν έχετε οποιαδήποτε αμφιβολία, παρακαλώ, μη διστάσετε να επικοινωνήσετε μαζί μου.