Mocking/stubbing Mongoose Modell save-Methode

Einer einfachen Mongoose Modell:

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;

Ich testen wollen, dieses Modell, aber ich ' m schlagen ein paar Straßensperren.

Meine aktuelle Skillung sieht ungefähr so aus (ein paar Sachen aus Platzgründen weggelassen):

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();
      });
    });
  });
});

Jedoch, mit diesen werde ich schlagen, meine Datenbank jedes mal, wenn ich den test ausführen, das würde ich lieber vermeiden.

Ich habe versucht, mit Mockgoose, aber dann ist mein test wird nicht ausgeführt.

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

Den test stecken bleibt, und wirft eine Fehlermeldung: Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test. ich habe versucht, die Erhöhung der timeout auf 20 Sekunden, aber das hat nichts lösen.

Weiter, warf ich Weg Mockgoose und versucht, mit Sinon zu stub die save nennen.

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();
    });
  });
});

Diesem test geht, aber es irgendwie nicht viel Sinn für mich. Ich bin ganz neu bei stubbing, lustig, was du hast, ... und ich bin mir nicht sicher, ob dies der richtige Weg zu gehen. Ich bin stubbing der save Methode auf post und dann bin ich auch behaupten es wurde genannt, aber ich bin natürlich nannte es... Auch, ich kann nicht scheinen, um auf die Argumente der nicht-gekürzte Mungo-Methode zurückkehren würde. Ich möchte vergleichen die post variable, um etwas, das die save Methode gibt, wie im ersten test, wo ich auf die Datenbank. Ich habe versucht, eine paar von Methoden aber Sie alle fühlen sich ganz hackish. Es muss eine saubere Art und Weise, nicht?

Paar Fragen:

  • Sollte ich ja vermeiden, auf die wie bei einer Datenbank habe ich immer überall gelesen? Meinem ersten Beispiel funktioniert gut und ich konnte löschen Sie die Datenbank nach jedem Lauf. Allerdings ist es nicht wirklich das Gefühl mir Recht sein.

  • Wie würde ich die stub-die save-Methode aus dem Mungo-Modell und stellen Sie sicher, dass es tatsächlich testet, was ich will, um zu testen: speichern eines neuen Objekts in die db.

  • Oleg ' s Antwort sieht gut aus, wenn Sie ein mockist TDDer, aber die meisten klassischen TDDers würde habe kein problem mit dem schlagen der Datenbank. Für eine Erklärung der mocks, stubs und mockist vs klassischen TDD siehe Martin Fowler ' s Artikel zum Thema.
  • Am Ende des Tages tests sind da, um zu garantieren, code Qualität, es gibt also kein schreiben oder falsch, solange die Qualität nicht darunter leiden. Die Nachteile von basic-unit-tests schlagen der DB sind: (1) die Geschwindigkeit, (2) Komplexität für CI und individuellen Projekt-Entwickler, (3) test Nebenwirkungen übertragen über DB-Zustand, zwischen den einzelnen tests oder gleichzeitigen Prüfung läuft, die schwierig zu lösen, (4) Festsetzung Fehler bedeutet zusätzlichen Aufwand für die Entwickler, im worst case externe ressourcenabhängigkeit. Es ist nichts falsch über all das, aber wirklich zur integration tests nur. Ich würde klar trennen die beiden.
  • Vergessen zu erwähnen: danke für den link zu einem sehr interessanten Artikel von Martin Fowler!
  • Ich Stimme mit all dem. Ich persönlich bin gut mit nicht mit unit-tests für die Persistenz-bezogenen code und Integrations-tests nur. Dies ergibt sich aus der "Verwendung realer Gegenstände wenn möglich" - Mentalität der klassischen TDD. Wollte ich nur geben, dass Sicht und einige Hintergrundinformationen, die auf den Fragesteller, da er sagt, dass er neu stubbing/mocking und möglicherweise nicht bewusst sein, integration-Tests bei allen.
InformationsquelleAutor cabaret | 2015-10-21
Schreibe einen Kommentar