Il peut être difficile de tester les modèles Mongoose car vous devez écrire des tests qui n'interfèrent pas avec votre base de données actuelle. Le package de serveur de mémoire MongoDB offre une solution simple. Il vous permet de stocker vos données de test dans la mémoire de l'application.

Dans ce didacticiel, vous allez créer un modèle Mongoose simple et écrire des tests à l'aide de Jest et du serveur de mémoire MongoDB.

Qu'est-ce que le serveur de mémoire MongoDB ?

La dernière chose que vous voulez est de sauvegarder de fausses données dans votre vraie base de données, ce qui pourrait arriver si vous vous y connectez pendant les tests. Au lieu de cela, vous pouvez choisir d'utiliser une instance MongoDB locale distincte pour stocker vos données. Bien que cela fonctionne, cela est irréalisable si vos tests s'exécutent sur le cloud. De plus, se connecter et interroger une base de données réelle lors de chaque test peut coûter cher.

Serveur de mémoire MongoDB, cependant, fait tourner un vrai serveur MongoDB et vous permet de stocker les données de test en mémoire. Cela le rend plus rapide que d'utiliser une base de données MongoDB locale puisque les données ne sont pas écrites sur un disque physique.

Création du modèle de mangouste

Les modèles Mongoose fournissent une interface pour s'interfacer avec la base de données MongoDB. Pour les créer, il faut les compiler à partir d'un schéma Mongoose, qui définit votre modèle de données MongoDB. Ce didacticiel utilisera un schéma pour un document de tâches. Il contiendra le titre et les champs complétés.

Exécutez la commande suivante dans le terminal pour créer un nouveau dossier et y accéder.

test du modèle de mangouste mkdir
CD test du modèle de mangouste

Initialisez npm avec la commande suivante :

npm init -y

La -y L'indicateur indique à npm de générer un fichier package.json avec des valeurs par défaut.

Exécutez cette commande pour installer le mangouste forfait:

npm installer mangouste

Créez un nouveau fichier appelé todo.model.js et définissez le schéma todo :

constante mangouste = exiger("mangouste")
constante { Schéma } = mangouste
constante TodoSchema = Nouveau Schéma({
Objet: {
taper: Chaîne de caractères,
obligatoire: vrai
},
terminé: {
taper: booléen,
obligatoire: vrai
}
})

À la fin de ce fichier, créez et exportez le modèle todo :

module.exportations = mangouste.model("Todo", TodoSchema)

Planification des tests

Lorsque vous écrivez des tests, vous voulez planifier à l'avance ce que vous allez tester. Cela garantit que vous testez toutes les fonctionnalités de votre modèle.

À partir du modèle Mongoose que nous avons créé, la tâche doit contenir un élément de type String et un champ complété de type Boolean. Ces deux champs sont obligatoires. Cela signifie qu'au minimum, notre test doit garantir :

  • Les éléments valides sont enregistrés avec succès dans la base de données.
  • Les éléments sans champs obligatoires ne sont pas enregistrés.
  • Les éléments avec des champs de type non valide ne sont pas enregistrés.

Nous écrirons ces tests dans un bloc de test car ils sont liés. Dans Jest, vous définissez ce bloc de test à l'aide de la décris fonction. Par exemple:

décris('Test du modèle à faire', () => {
// Vos tests vont ici
}

Configuration de la base de données

Pour configurer un serveur de mémoire MongoDB, vous allez créer une nouvelle instance de serveur de mémoire Mongo et vous connecter à Mongoose. Vous allez également créer des fonctions qui seront chargées de déposer toutes les collections dans la base de données et de se déconnecter de l'instance du serveur de mémoire Mongo.

Exécutez la commande suivante pour installer mongodb-memory-server.

npm installer mongodb-Mémoire-serveur

Créez un nouveau fichier appelé setuptestdb.js et importez mongoose et mongodb-memory-server.

constante mangouste = exiger("mangouste");
constante { MongoMemoryServer } = exiger("mongodb-memory-server");

Ensuite, créez une fonction connectDB(). Cette fonction crée une nouvelle instance de serveur de mémoire Mongo et se connecte à Mongoose. Vous l'exécuterez avant tous les tests pour vous connecter à la base de test.

laisser mongo = nul;

constante connectDB = asynchrone () => {
mongo = attendre MongoMemoryServer.create();
constante uri = mongo.getUri();

attendre mangouste.connect (uri, {
useNewUrlParser: vrai,
useUnifiedTopology: vrai,
});
};

Créez une fonction dropDB() en ajoutant le code suivant. Cette fonction supprime la base de données, ferme la connexion Mongoose et arrête l'instance de serveur de mémoire Mongo. Vous exécuterez cette fonction une fois tous les tests terminés.

constante dropDB = asynchrone () => {
si (mongo) {
attendremangouste.lien.dropDatabase();
attendremangouste.lien.proche();
attendre mongo.stop();
}
};

La dernière fonction que vous allez créer s'appelle dropCollections(). Il supprime toutes les collections Mongoose créées. Vous l'exécuterez après chaque test.

constante dropCollections = asynchrone () => {
si (mongo) {
constante collections = attendre mongoose.connection.db.collections();
pour (laisser le recueil de collections) {
attendre collection.remove();
}
}
};

Enfin, exportez les fonctions conenctDB(), dropDB() et dropCollections().

module.exportations = { connectDB, dropDB, dropCollections}

Rédaction des épreuves

Comme mentionné, vous utiliserez Jest pour écrire les tests. Exécutez la commande suivante pour installer jest.

npm installer plaisanter

Dans le package.json fichier, configurez jest. Remplacez votre bloc "scripts" existant par ce qui suit :

"scénarios": {
"test": "blague --runInBand --detectOpenHandles"
},
"plaisanter": {
"testEnvironment": "nœud"
},

Créez un nouveau fichier appelé todo.model.test.js et importez la bibliothèque mongoose, le modèle todo et les fonctions conenctDB(), dropDB() et dropCollections() :

constante mangouste = exiger("mangouste");
constante { connectDB, dropDB, dropCollections } = exiger(""./setupdb");
constante À faire = exiger(""./todo.model");

Vous devez exécuter la fonction connectDB() avant l'exécution de tous les tests. Avec Jest, vous pouvez utiliser la méthode beforeAll().

Vous devez également exécuter des fonctions de nettoyage. Après chaque test, exécutez la fonction dropCollections() et la fonction dropDB() après tous les tests. Vous n'avez pas besoin de le faire manuellement et vous pouvez utiliser les méthodes afterEach() et afterAll() de Jest.

Ajoutez le code suivant au fichier todo.model.test.js pour configurer et nettoyer la base de données.

avant tout(asynchrone () => {
attendre connectDB();
});

après tout(asynchrone () => {
attendre dropDB();
});

après chaque(asynchrone () => {
attendre dropCollections();
});

Vous êtes maintenant prêt à créer les tests.

Le premier test vérifiera si l'élément todo a été inséré avec succès dans la base de données. Il vérifiera si l'identifiant de l'objet est présent dans le fichier créé et si les données qu'il contient correspondent à celles que vous avez envoyées à la base de données.

Créez un bloc de description et ajoutez le code suivant.

décris("Modèle à faire", () => {
ce("devrait créer un élément todo avec succès", asynchrone () => {
laisser validTodo = {
Objet: "Faire la vaisselle",
complété: faux,
};
constante newTodo = attendre Todo (validTodo);
attendre newTodo.save();
attendre(nouveauTodo._identifiant).à définir();
attendre(nouveauTodo.Objet).être(validTodo.Objet);
attendre(nouveauTodo.complété).être(validTodo.complété);
});
});

Cette crée un nouveau document dans la base de données contenant les données dans la variable validTodo. L'objet renvoyé est ensuite validé par rapport aux valeurs attendues. Pour que ce test réussisse, la valeur renvoyée doit avoir un ID d'objet. En outre, les valeurs des champs item et complete doivent correspondre à celles de l'objet validTodo.

En plus de tester le cas d'utilisation normal, vous devez également tester un cas d'utilisation défaillant. À partir des tests que nous avons planifiés, vous devez tester le modèle mangouste avec un objet todo, avec un champ obligatoire manquant et un avec un type incorrect.

Ajoutez un deuxième test au même bloc de description, comme suit :

 ce("devrait échouer pour l'élément todo sans champs obligatoires", asynchrone () => {
laisser invalidTodo = {
Objet: "Faire la vaisselle",
};
essayer {
constante newTodo = Nouveau Todo (invalidTodo);
attendre newTodo.save();
} attraper (Erreur) {
attendre(Erreur).toBeInstanceOf(mangouste.Erreur.Erreur de validation);
attendre(Erreur.les erreurs.complété).à définir();
}
});

Le modèle de mangouste Todo attend à la fois l'élément et les champs complétés. Cela devrait générer une erreur si vous essayez d'enregistrer une tâche sans l'un de ces champs. Ce test utilise le bloc try…catch pour intercepter l'erreur renvoyée. Le test s'attend à ce que les erreurs soient une erreur de validation mangouste et proviennent du champ rempli manquant.

Pour tester si le modèle génère une erreur si vous utilisez des valeurs du mauvais type, ajoutez le code suivant au bloc describe.

 ce("devrait échouer pour l'élément todo avec des champs de type incorrect", asynchrone () => {
laisser invalidTodo = {
Objet: "Faire la vaisselle",
complété: "Faux"
};
essayer {
constante newTodo = Nouveau Todo (invalidTodo);
attendre newTodo.save();
} attraper (Erreur) {
attendre(Erreur).toBeInstanceOf(mangouste.Erreur.Erreur de validation);
attendre(Erreur.les erreurs.complété).à définir();
}
});

Notez que la valeur du champ complété est une chaîne au lieu d'un booléen. Le test s'attend à ce qu'une erreur de validation soit générée car le modèle attend une valeur booléenne.

MongoMemoryServer et Jest forment une excellente équipe

Le package npm mongo-memory-server fournit une solution simple pour tester les modèles Mongoose. Vous pouvez stocker des données factices en mémoire sans toucher à la base de données de votre application.

Vous pouvez utiliser MongoMemoryServer avec Jest pour écrire des tests pour les modèles Mongoose. Notez qu'il ne couvre pas tous les tests possibles que vous pouvez écrire pour vos modèles. Ces tests dépendront de votre schéma.