85 votes

Mocker une base de données dans node.js ?

Comment puis-je simuler la base de données dans mon application node.js, qui dans ce cas utilise mongodb comme backend pour l'API REST d'un blog ?

Bien sûr, je pourrais définir la base de données sur une base spécifique. testing -mais je continuerais à enregistrer des données et à tester non seulement mon code, mais aussi la base de données, de sorte que je ne fais pas de tests unitaires, mais des tests d'intégration.
Que faire alors ? Créer des wrappers de base de données comme couche intermédiaire entre l'application et la base de données et remplacer le DAL lors des tests ?

// app.js  
var express = require('express');
    app = express(),
    mongo = require('mongoskin'),
    db = mongo.db('localhost:27017/test?auto_reconnect');

app.get('/posts/:slug', function(req, res){
    db.collection('posts').findOne({slug: req.params.slug}, function (err, post) {
        res.send(JSON.stringify(post), 200);
    });
});

app.listen(3000);

// test.js
r = require('requestah')(3000);
describe("Does some testing", function() {

  it("Fetches a blogpost by slug", function(done) {
    r.get("/posts/aslug", function(res) {
      expect(res.statusCode).to.equal(200);
      expect(JSON.parse(res.body)["title"]).to.not.equal(null);
      return done();
    });

  });
));

138voto

slebetman Points 28276

Je ne pense pas qu'un code lié à une base de données puisse être correctement testé sans être testé avec le logiciel de la base de données. En effet, le code que vous testez n'est pas seulement du javascript, mais aussi la chaîne de requête de la base de données. Même si, dans votre cas, les requêtes semblent simples, vous ne pouvez pas compter sur le fait qu'il en sera toujours ainsi.

Par conséquent, toute couche d'émulation de base de données mettra nécessairement en œuvre l'intégralité de la base de données (à l'exception, peut-être, du stockage sur disque). Vous finissez alors par effectuer des tests d'intégration avec l'émulateur de base de données, même si vous appelez cela des tests unitaires. Un autre inconvénient est que l'émulateur de base de données peut finir par avoir un ensemble différent de bogues par rapport à la base de données et vous pouvez finir par devoir coder à la fois pour l'émulateur de base de données et la base de données (un peu comme la situation avec IE vs Firefox vs Chrome, etc.)

C'est pourquoi, à mon avis, la seule façon de tester correctement votre code est de l'interfacer avec la base de données réelle.

46voto

christkv Points 2650

Il existe une règle générale en matière d'imitation qui est la suivante

Ne vous moquez pas de ce qui ne vous appartient pas.

Si vous souhaitez simuler la base de données, cachez-la derrière une couche de service abstraite et simulez cette couche. Veillez ensuite à tester l'intégration de la couche de service réelle.

Personnellement, je me suis éloigné de l'utilisation des mocks pour les tests et je les utilise pour la conception de haut en bas, ce qui m'aide à conduire le développement de haut en bas en simulant les couches de service au fur et à mesure que j'avance, puis en implémentant ces couches et en écrivant des tests d'intégration. Utilisées comme outil de test, elles ont tendance à rendre vos tests très fragiles et, dans le pire des cas, conduisent à une divergence entre le comportement réel et le comportement simulé.

45voto

PositiveGuy Points 3245

Je ne suis pas d'accord avec la réponse choisie ni avec les autres réponses reçues jusqu'à présent.

Ne serait-ce pas génial si vous pouviez détecter les erreurs engendrées par les changements chaotiques et souvent désordonnés apportés aux schémas de la base de données et à votre code AVANT qu'il n'arrive à l'assurance qualité ? Je parie que la majorité des personnes interrogées répondraient "oui" !

Vous pouvez et devez certainement isoler et tester les schémas de votre base de données. Et vous ne le faites pas sur la base d'un émulateur ou d'une image lourde ou d'une recréation de votre base de données et de votre machine. C'est la raison d'être de SQLite, pour ne citer qu'un exemple. Vous le simulez sur la base d'une instance légère en mémoire fonctionnant avec des données statiques qui ne changent pas dans cette instance en mémoire, ce qui signifie que vous testez vraiment votre base de données de manière isolée et que vous pouvez faire confiance à vos tests. Et évidemment, c'est rapide parce que c'est en mémoire, un squelette, et c'est mis au rebut à la fin de l'exécution d'un test.

Donc oui, vous devriez tester le SCHEMA qui est exporté dans une instance en mémoire très légère du moteur de base de données que vous utilisez, et qui, avec l'ajout d'une très petite quantité de données statiques, devient votre base de données simulée isolée.

Vous exportez périodiquement (de manière automatisée) vos schémas réels de votre vraie base de données et vous les importez/mettez à jour dans votre instance de base de données légère en mémoire avant chaque envoi à l'assurance qualité et vous saurez instantanément si les dernières modifications apportées à la base de données par vos administrateurs de base de données ou par d'autres développeurs qui ont modifié le schéma dernièrement ont cassé des tests.

Bien que j'applaudisse l'effort de faire de son mieux pour répondre, j'attribuerais un vote négatif à la réponse actuelle si je le pouvais, mais je suis nouveau et je n'ai pas encore acquis suffisamment de réputation pour être en mesure de le faire.

Quant à la personne qui a répondu "ne vous moquez pas de ce qui ne vous appartient pas", je pense qu'elle voulait dire "ne testez rien". Je pense qu'il voulait dire "ne testez pas ce que vous ne possédez pas". Mais on se moque des choses que l'on ne possède pas ! Parce que ce sont les choses qui ne sont pas testées qui doivent être isolées !

J'ai l'intention de partager le COMMENT avec vous et je mettrai à jour ce post dans le futur avec un exemple réel de code JS !

C'est ce que font en permanence de nombreuses équipes pilotées par les tests. Il suffit de comprendre le comment.

5voto

cirrus Points 2354

L'approche que je préfère pour tester unitairement le code de la base de données dans n'importe quel langage est d'accéder à Mongo par le biais d'une abstraction de référentiel (il y a un exemple ici). http://iainjmitchell.com/blog/?p=884 ). Les implémentations varieront en termes de fonctionnalités spécifiques de DB exposées, mais en supprimant tout le code Mongo de votre propre logique, vous êtes en mesure d'effectuer des tests unitaires. Il suffit de remplacer l'implémentation du référentiel Mongo par une version stubbed out, ce qui est trivialement facile. Par exemple, il suffit de stocker les objets dans une simple collection de dictionnaires en mémoire.

Vous obtiendrez les avantages des tests unitaires de votre propre code de cette façon sans dépendances de la base de données, mais vous devrez toujours faire des tests d'intégration avec la base de données principale parce que vous ne serez probablement jamais en mesure d'émuler les idiosyncrasies de la base de données réelle, comme d'autres l'ont dit ici. Le genre de choses que j'ai trouvées est aussi simple que l'indexation en mode sans échec ou sans mode sans échec. Plus précisément, si vous avez un index unique, votre implémentation de mémoire fictive peut l'honorer dans tous les cas, mais Mongo ne le fera pas sans safe-mode.

Ainsi, bien que vous ayez toujours besoin de tester la base de données pour certaines opérations, vous serez certainement en mesure de tester votre propre logique de manière unitaire avec une implémentation du référentiel.

4voto

Michael Cole Points 351

Le but du mocking est d'éviter la complexité et de tester son propre code à l'unité. Si vous voulez écrire des tests e2e, utilisez la db.

Écrire du code pour configurer une base de données de test pour les tests unitaires est une dette technique et incroyablement insatisfaisant.

Il existe des bibliothèques fictives dans npm :

Mongo - https://www.npmjs.com/package/mongomock

mangouste - https://www.npmjs.com/package/mockgoose

Si ces derniers ne prennent pas en charge les fonctionnalités dont vous avez besoin, alors oui, vous devrez peut-être utiliser le vrai produit.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X