Moqueur/stubbing Mangouste modèle méthode save

Donné un simple Mangouste modèle:

import mongoose, { Schema } from 'mongoose';

const PostSchema = Schema({
  title:    { type: String },
  postDate: { type: Date, default: Date.now }
}, { timestamps: true });

const Post = mongoose.model('Post', PostSchema);

export default Post;

Je souhaite tester ce modèle, mais je suis de frapper quelques obstacles.

Mon spec actuelle ressemble à quelque chose comme ceci (certains trucs omis par souci de concision):

import mongoose from 'mongoose';
import { expect } from 'chai';
import { Post } from '../../app/models';

describe('Post', () => {
  beforeEach((done) => {
    mongoose.connect('mongodb://localhost/node-test');
    done();
  });

  describe('Given a valid post', () => {
    it('should create the post', (done) => {
      const post = new Post({
        title: 'My test post',
        postDate: Date.now()
      });

      post.save((err, doc) => {
        expect(doc.title).to.equal(post.title)
        expect(doc.postDate).to.equal(post.postDate);
        done();
      });
    });
  });
});

Cependant, avec cela, je suis de frapper ma base de données chaque fois que je lance le test, que je préférerais éviter.

J'ai essayé d'utiliser Mockgoose, mais alors mon test ne fonctionne pas.

import mockgoose from 'mockgoose';
//in before or beforeEach
mockgoose(mongoose);

Le test est coincé et renvoyait un message d'erreur disant: Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test. j'ai tenté d'augmenter le délai d'attente de 20 secondes, mais ça n'a pas de résoudre quoi que ce soit.

Ensuite, j'ai jeté Mockgoose et essayé d'utiliser Sinon à talon la save appel.

describe('Given a valid post', () => {
  it('should create the post', (done) => {
    const post = new Post({
      title: 'My test post',
      postDate: Date.now()
    });

    const stub = sinon.stub(post, 'save', function(cb) { cb(null) })
    post.save((err, post) => {
      expect(stub).to.have.been.called;
      done();
    });
  });
});

Ce test réussit, mais de toute façon il n'a pas beaucoup de sens pour moi. Je suis assez nouveau à écrasant, en se moquant, qu'avez-vous, ... et je ne suis pas sûr si c'est la bonne façon d'aller. Je suis cogner la save méthode sur post, et puis je suis en affirmant qu'il a été appelé, mais je suis évidemment en l'appelant... Aussi, je n'arrive pas à obtenir les arguments du non-écrasa Mangouste méthode serait de retour. Je voudrais comparer le post variable de quelque chose de la save méthode renvoie, comme dans le tout premier test où j'ai frappé la base de données. J'ai essayé un couple de méthodes mais ils sont tous sentir très à l'hackish. Il doit y avoir un moyen propre, non?

Quelques questions:

  • Dois-je en effet éviter de heurter la base de données comme je l'ai toujours lu partout? Mon premier exemple fonctionne très bien et j'ai pu effacer la base de données après chaque course. Cependant, il ne se sent pas vraiment le droit de me.

  • Comment pourrais-je le talon de la méthode d'enregistrement de la Mangouste modèle et assurez-vous qu'il fait des tests de ce que j'ai envie de tester: l'enregistrement d'un nouvel objet à la db.

  • Oleg réponse semble bon si vous êtes un mockist TDDer, mais plus classique TDDers serait n'ai pas de problème avec les coups de la base de données. Pour une explication sur les objets fantaisie, des talons, et mockist vs classique TDD voir Martin Fowler article sur le sujet.
  • À la fin de la journée, les tests sont là pour garantir la qualité du code, donc il n'y a pas d'écrire ou de mal, tant que la qualité n'en souffre pas. Les inconvénients de l'unité de base des tests de frapper la DB sont: (1) la vitesse, (2) la complexité de l'IC et de l'individu développeurs du projet, (3) test d'effets secondaires transférés via la DB de l'état, entre les tests individuels ou simultanée de test, qui sont difficiles à résoudre, (4) fixation bug signifie effort supplémentaire pour les développeurs, dans le pire des cas externes de dépendance de la ressource. Il n'y a rien de mal à ce sujet, mais vraiment pour les tests d'intégration uniquement. Je voudrais bien séparer les deux.
  • J'ai oublié de mentionner: merci pour le lien à un très intéressant article de Martin Fowler!
  • Je suis d'accord avec tout cela. Personnellement, je suis très bien de ne pas avoir de tests unitaires pour la persistance de code et avoir des tests d'intégration uniquement. Cela provient de la "utilisation des objets réels, si possible, la" mentalité de classique TDD. Je voulais juste donner ce point de vue et un peu de fond sur ce à la personne depuis qu'il a dit qu'il est à nouveau à écrasant/moqueur et peuvent ne pas être conscients de tests d'intégration à tous.
InformationsquelleAutor cabaret | 2015-10-21