2017-06-10 1 views
0

Ich bin ein Neuling für das JavaScript-Ökosystem. Ich versuche, einige API-Tests für meine REST-APIs mit Mocha/Chai zu schreiben. Meine Anforderung ist, dass ich meine Datenbank aufräumen muss, bevor ich die Testfälle ausführe. So schrieb ich den folgenden Code in einer Datei namens dbCleanup.jsWie erzwinge ich before() vor dem Ausführen von Tests in Mocha?

var config = require("config.json"); 
const pg = require('pg'); 

var connectionString = config.pgConnectionString 
console.log("DB Connection String: ", connectionString) 

function dbCleanup() { 

    var dbTables = ["projects", "employees"]; 

    var pgClient = new pg.Client(connectionString); 

    var promise = new Promise(function (resolve, reject) { 
     pg.connect(connectionString, (err, pgClient, done) => { 
      if (err) { 
       done(); 
       console.log(err); 
       reject(); 
      } 

      for (i = 0; i < dbTables.length; i++) { 
       query = "TRUNCATE " + dbTables[i] + " CASCADE;" 
       pgClient.query(query, function (err, res) { 
        if (err) { 
         done(); 
         console.error('error running query', err); 
         reject(); 
        } 
        resolve(); 
       }); 
      } 
     }); 
    }); 

    pgClient.end() 

    return promise; 
} 

exports.dbCleanup = dbCleanup; 

Ich habe eine andere Datei namens globalBefore.js, wo ich den folgenden Code haben:

var dbCleanup = require('./dbCleanup.js').dbCleanup; 

function _beforeClean(done) { 
    try { 
     dbCleanup() 
      .then(done) 
    } catch (err) { 
     console.error(err); 
    } 
} 

exports.beforeCleanup = _beforeClean; 

Jetzt in meinem Mokka test.js Datei, ich versuche, die Datenbankbereinigung Funktion aufzurufen, wie folgt:

var request = require("request"); 
var rp = require("request-promise"); 
var config = require("../config.json"); 
var expect = require('chai').expect; 
var data = require("./data.json"); 

var globalBefore = require("../globalBefore.js"); 


describe("POST /employees/", function() { 

    console.log("clearing db tables...") 
    before(globalBefore.beforeCleanup, function (done) { 
     done(); 
    }); 

    beforeEach(function (done) { 
    ... do some business logic related work here ... 
    }); 


    it.only('Try create an employee', function (done) { 
    ... API call to create an employee and use Chai assertions to validate ... 
    }); 
}); 

Das Problem, mit dem ich konfrontiert bin, ist, Mocha geht weiter mit dem Ausführen meiner Tests noch bevor die dbCleanup() - Funktion abgeschlossen ist. Das führt dazu, dass meine Datenbank kaputt geht und ich auf unerwünschtes Verhalten stoße.

Kann jemand aus der SO-Community helfen? Ich habe verschiedene Optionen ausprobiert, die ich im Internet finden konnte, konnte das Problem jedoch nicht beheben. Wie im Codefragment gezeigt, ich hoffte, dass ein Versprechen verwenden, sollten

Um allgemeinere das Problem gelöst haben, wie erzwingen ich die Anweisungen innerhalb eines vor Klausel vor Mocha abzuschließen führt die es Klauseln Die Tests?

Danke!

Antwort

1

Sie verwenden before den falschen Weg. Versuchen Sie stattdessen:

before(function (done) { 
    globalBefore.beforeCleanup(done); 
}); 

oder

before(globalBefore.beforeCleanup); 

Und in globalBefore.js:

var dbCleanup = require('./dbCleanup.js').dbCleanup; 

function _beforeClean(done) { 
    dbCleanup().then(done).catch(done); 
} 

exports.beforeCleanup = _beforeClean; 

Beispiel (I nur dbCleanup.js verändert eine andere Versprechen zu verwenden)

dbCleanup.js

function dbCleanup() { 

    return new Promise(function (resolve, reject) { 
     setTimeout(resolve, 2000); 
    }); 

} 

exports.dbCleanup = dbCleanup; 

globalBefore.js

var dbCleanup = require('./dbCleanup.js').dbCleanup; 

function _beforeClean(done) { 
    dbCleanup().then(done).catch(done); 
} 

exports.beforeCleanup = _beforeClean; 

index.js

var globalBefore = require("../globalBefore.js"); 

describe("POST /employees/", function() { 

    this.timeout(5000); // because the promise take 2000ms 

    console.log("clearing db tables...") 
    before(function (done) { 
     console.log('before calling beforeCleanup'); 
     globalBefore.beforeCleanup(function() { 
      console.log('after calling beforeCleanup'); 
      done(); // done cleaning db 
     }); 
    }); 

    /* Without the console.logs 
    console.log("clearing db tables..."); 
    before(globalBefore.beforeCleanup) 
    */ 

    beforeEach(function (done) { 
     // ... do some business logic related work here ... 
     console.log('beforeEach'); 
     done(); 
    }); 


    it.only('Try create an employee', function (done) { 
     // ... API call to create an employee and use Chai assertions to validate ... 
     console.log('it'); 
     done(); 
    }); 
}); 

OUTPUT

clearing db tables... 

    POST /employees/ 
before calling beforeCleanup 
after calling beforeCleanup 
beforeEach 
it 
    √ Try create an employee 


    1 passing (2s) 

https://mochajs.org/#hooks

+0

Vielen Dank für Ihre Antwort. Ich habe beide Optionen ausprobiert und stoße auf das gleiche Problem. Meine Tests werden ausgeführt, noch bevor die dbCleanup() - Funktion abgeschlossen ist.Ich frage mich jetzt, ob meine Aufräumfunktion und die Art, wie ich Promises benutze, tatsächlich ihren Teil oder nicht tut :-( –

+0

Sie haben auch einen Fehler mit dem 'try/catch', für Versprechungen müssen Sie' Promise.catch verwenden '' Ich änderte das und fügte ein funktionierendes Beispiel hinzu. – luisenrike

+0

Vielen Dank @luisenrike für die Detaillierung der Lösung. Das funktionierte für mich. –

Verwandte Themen