2012-06-10 6 views
15

Ich versuche, eine eigenständige Test-Suite mit Mocha zu erstellen, die in einer perfekten Welt meine express.js Anwendung starten würde, Zombie verwenden, um eine Seite zu rendern, einen Haufen zu überprüfen von Sachen und dann teardown/kill die express.js Anwendung.Setup/Teardown von express.js Anwendung mit Mokka

Gibt es einen einfachen/besten Weg, dies zu tun?

NB. Ich könnte einfach den Express-Anwendungsserver laufen lassen, bevor ich die Tests durchführe, aber was nützen Yaks, wenn Sie sie nicht rasieren werden.

+2

Nizza Frage.Ich selbst habe mich eine Weile damit beschäftigt, aber nach einer Woche habe ich einfach aufgegeben. Ich fand Zombie wirklich nervig, mit zu arbeiten. Ich habe viel über PhantomJS gelesen, aber ich habe es nicht selbst versucht. – Pickels

Antwort

23

Zuerst müssen Sie Ihre tatsächliche App in ein Modul verschieben und in die Datei importieren, die Ihre App startet. Nun, da dies separat ist, können Sie die App in ihrem vollständigen Zustand haben, bevor Sie tatsächlich zuhören.

Sie sollten die tatsächliche Einrichtung Ihrer App in eine separate Datei verschieben, nennen wir sie app.js, können Sie von der Datei, aus der Sie den Knoten ausführen, abhören, nennen wir sie index.js.

So würde app.js wie folgt aussehen:

var express = require('express') 
    , routes = require('./routes'); 

var app = module.exports = express.createServer(); 

// Configuration 

app.configure(function(){ 
    app.set('views', __dirname + '/views'); 
    app.set('view engine', 'jade'); 
    app.use(express.bodyParser()); 
    app.use(express.methodOverride()); 
    app.use(app.router); 
    app.use(express.static(__dirname + '/public')); 
}); 

app.configure('development', function(){ 
    app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); 
}); 

app.configure('production', function(){ 
    app.use(express.errorHandler()); 
}); 

// Routes 

app.get('/', routes.index); 

und index.js würde wie folgt aussehen:

var app = require('./app'); 

app.listen(3000, function(){ 
    console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env); 
}); 

Das Laden von Ihrer App seperates es tatsächlich hören mit, so dass Sie Laden Sie diese App in Ihre Unit-Tests.

In Ihren Komponententests würden Sie etwas in einer Setup-Methode und Teardown-Methode tun, um den Server hoch und runter zu bringen.

in der Datei Test/app_tests.js:

describe('app', function(){ 
    var app = require('../app'); 
    beforeEach(function(){ 
    app.listen(3000); 
    }); 
    // tests here 
    afterEach(function(){ 
    app.close(); 
    }) 
}); 
+0

Super! Aber in meinem Fall habe ich mehrere Testdateien und es scheint, dass Mocha alle Dateien gleichzeitig ausführt, was zu einigen schlechten Konflikten zwischen Testdateien führt! Was kann ich tun ? –

+0

Lassen Sie jeden Test auf einen anderen Port hören - wählen Sie einfach eine Zufallszahl (hoch genug) –

+0

AUSGEZEICHNETE LÖSUNG! Das ist der richtige Weg. Eine Änderung: Sie sollten eigentlich das Ergebnis von app.listen schließen, nicht die App selbst, dh: (in beforeEach) "instance = app.listen (3000);" ... und dann (in afterEach) "instance.close()" –

4

Neben Oved D Antwort.

Beschreiben Sie Ihre App in Express-app.js oder eine andere Datei:

module.exports = function (o) { 
    o = o || {}; 
    var app = express(); 

    // app.configure 
    // configure routes 
    if (o.someOption) { 
    // some additional test code 
    } 

    return app; 
} 

beschreiben Tests in Test/01-some.js:

var expressApp = require('../express-app'); 
describe('some', function() { 

    // just describe needed vars 
    var app, server, port; 

    // describe setup 
    before(function (next) { 
    // create app when 
    app = expressApp({routes: /api\/some\/.*/ /* put here some test options ...*/}); 
    // creating listener with random port 
    server = app.listen(function() { 
     // store port when it ready 
     port = server.address().port; 
     // and go to tests 
     next(); 
    }); 
    }); 

    // tests 
    it('should return valid result', function (done) { 
    // do a simple request to /api/some 
    http.request({ 
     host: 'localhost', 
     port: port, 
     path: '/api/some' 
    }, function (res) { 
     if (res.err) throw new Error(res.err); 
     done(); 
    }); 
    }); 

    // teardown 
    after(function() { 
    // stop listening that port 
    server.close(); 
    }); 

}); 

Fertig. ;-)

Jetzt können Sie beliebig viele Tests erstellen. Ich empfehle Ihnen, nur erforderliche URLs und Dienste in Tests zu aktivieren, indem Sie sie definieren, indem Sie params an das Modul express-app.js übergeben.


Update:

nicht sicher, wie es in mocha funktioniert aber besser before und after Anrufe init.js zu bewegen und es mit mocha --require init.js zu laden.

Datei sollte so aussieht:

// use it in your mocha tests 
global.setupEnv = function setupEnv (o, before, after) { 

    // just describe needed vars 
    var env = Object.create(null); 

    // setup 
    before(function (next) { 
     // create app 
     env.app = expressApp(o); 
     // creating listener with random port 
     env.server = env.app.listen(function() { 
      // store port when it ready 
      port = env.server.address().port; 
      env.app.log('Listening on ', env.port); 
      // and go to tests 
      next(); 
     }); 
    }); 

    // teardown 
    after(function() { 
     // stop listening that port 
     env.server.close(); 
    }); 

    return env; 
} 

Und in Ihren Tests:

// requiring dependencies 
var request = require('request'); 

describe('api', function() { 

    // describe setup 
    var env = global.setupEnv({ 
      routes: 'api/some' 
     }, before, after); 

    // tests 
    it('should pass', function (done) { 
     request('http://localhost:' + env.port, function (error, response, body) { 
      done(); 
     }); 
    }); 

});