2014-08-30 15 views
10

Ich versuche, einen Test zu schreiben, um eine Methode zu testen, die zu mongo verbindet, aber ich möchte nicht tatsächlich mongo laufen lassen und tatsächlich eine Verbindung zu ihr herstellen, um meine Tests erfolgreich durchlaufen zu lassen.Wie testet man eine Methode, die sich mit Mongo verbindet, ohne tatsächlich eine Verbindung zu Mongo herzustellen?

Hier ist mein aktueller Test, der erfolgreich ist, wenn mein Mongo-Daemon läuft.

describe('with a valid mongo string parameter', function() { 
    it('should return a rejected promise', function(done) { 
     var con = mongoFactory.getConnection('mongodb://localhost:27017'); 
     expect(con).to.be.fulfilled; 
     done(); 
    }); 
}); 

mongoFactory.getConnection Code:

getConnection: function getConnection(connectionString) { 

     // do stuff here 

     // Initialize connection once 
     MongoClient.connect(connectionString, function(err, database) { 
      if (err) { 
      def.reject(err); 
      } 

      def.resolve(database); 
     }); 

     return def.promise; 
    } 
+0

Ein guter Grund, warum ich das will, ist, dass meine Unit-Tests alle darauf angewiesen sind, tatsächlich mit Mongo zu verbinden, so dass sie fehlschlagen, wenn Mongod nicht läuft. Was bedeutet, dass sie alle versagen, wenn sie zum Beispiel auf travis ci gebaut werden. – Catfish

+0

möglich Duplikat von: http://stackoverflow.com/questions/12526160/mocking-database-in-node-js und http://stackoverflow.com/questions/10378116/mock-test-mongodb-database-node-js – zamnuts

+0

keine Erfahrung damit, aber auf den ersten Blick Sinon.JS könnte helfen, Stubs und Mocks zu verwenden: https://www.npmjs.org/package/sinon – zamnuts

Antwort

28

Es gibt ein paar Antworten von SO zu Unit-Tests Code verwendet, die MongoDB als Datenspeicher verwendet:

ich einen Versuch machen, werden diese Lösungen zu konsolidieren.

Präambel

In erster Linie Sie sollten wollen MongoDB ausgeführt werden, während die Tests durchführen. Die Abfragesprache von MongoDB ist komplex, daher müssen legitime Abfragen für eine stabile MongoDB-Instanz ausgeführt werden, um sicherzustellen, dass Ihre Abfragen wie geplant ausgeführt werden und Ihre Anwendung ordnungsgemäß auf die Ergebnisse reagiert. In diesem Sinne sollten Sie jedoch niemals Ihre Tests gegen ein Produktionssystem ausführen, sondern stattdessen ein Peripheriesystem zu Ihrer Integrationsumgebung. Dies kann auf dem gleichen Computer wie Ihre CI-Software geschehen oder einfach relativ nah an dieser (in Bezug auf den Prozess, nicht unbedingt Netzwerk oder geografisch).

Dieses ENV könnte eine geringe Grundfläche haben und vollständig im Speicher ausgeführt werden (resource 1) (resource 2), würde aber nicht unbedingt die gleichen Leistungsmerkmale wie Ihre Produktions-ENV erfordern. (Wenn Sie Performance-Test wollen, sollte dies ohnehin in einer separaten Umgebung von Ihrem CI behandelt werden.)

Setup-

  • Installieren Sie einen mongod Service speziell für CI. Wenn Repl Sets und/oder Sharding von Interesse sind (zB Bedenken schreiben, keine Verwendung von $isolated, etc.), ist es möglich, eine Clusterumgebung nachzubilden, indem mehrere Instanzen mongod ausgeführt werden (1 Konfig, 2x2 Daten für Shard + Repl) und eine mongos Instanz auf dem gleichen Rechner entweder mit einigen init.d-Skripten/Tweaks oder etwas wie Docker.
  • Verwenden Sie in Ihrer Anwendung umgebungsspezifische Konfigurationen (entweder über .json-Dateien eingebettet oder an einem Ort wie/etc, /home/user/.your-app oder ähnlich). Ihre Anwendung kann diese basierend auf einem node environment variable like NODE_ENV=int laden. Innerhalb dieser Konfigurationen unterscheiden sich Ihre db-Verbindungszeichenfolgen. Wenn Sie nicht mit env-spezifischen Konfigurationen sind, starten Sie dies als Mittel, um die Laufzeiteinstellungen der Anwendung zu abstrahieren (zB "local", "dev", "int", "pre", "prod" usw.) . Ich kann ein Muster auf Anfrage zur Verfügung stellen.
  • Enthalten Sie testorientierte Fixtures mit Ihrer Anwendungs-/Testsuite. Wie in einer der verknüpften Fragen erwähnt, unterstützt der Node.js-Treiber von MongoDB einige Hilfsbibliotheken: mongodb-fixtures and node-database-cleaner. Fixtures bieten einen funktionierenden und konsistenten Datensatz zum Testen: man denke an sie als Bootstrap.

Baut/Tests

  1. Reinigen Sie die zugehörige Datenbank so etwas wie node-database-cleaner verwenden.
  2. Füllen Sie Ihre Geräte in die jetzt leere Datenbank mit Hilfe von mongodb-fixtures.
  3. Führen Sie Ihren Build und Test durch.
  4. Wiederholen.

Auf der anderen Seite ...

Wenn Sie immer noch, dass nicht läuft MongoDB entscheiden ist der richtige Ansatz (and you wouldn't be the only one), dann ruft der Fahrer Ihre Datenspeicher abstrahiert mit einem ORM die beste ist Wette (für die gesamte Anwendung, nicht nur Testen). Zum Beispiel etwas wie model claims to be database agnostic, obwohl ich es noch nie benutzt habe. Bei Verwendung dieses Ansatzes würden Sie immer noch Fixtures und env-Konfigurationen benötigen, jedoch müssten Sie MongoDB nicht installieren. Der Vorbehalt hier ist, dass Sie dem von Ihnen gewählten ORM ausgeliefert sind.

-2

Sie könnten versuchen tingodb.

TingoDB ist ein eingebettetes JavaScript In-Process-Dateisystem oder eine In-Memory-Datenbank, die auf API-Ebene aufwärts mit MongoDB kompatibel ist.

+2

Aus Tingodb's README: "Upwards-kompatibel bedeutet, dass wenn Sie eine App erstellen, die verwendet Funktionalität, die von TingoDB implementiert wird, können Sie fast ohne Codeänderungen zu MongoDB wechseln. " Das bedeutet, wenn Sie MongoDB verwenden, können Sie nicht zu TingoDB wechseln. – zamnuts

+0

Nein, das bedeutet, dass nicht alle von MongoDB implementierten Funktionen von TingoDB unterstützt werden, aber die häufigste Untergruppe ist dort vorhanden. Deshalb habe ich speziell "Ting" Tingodb gesagt. –