65 votes

Comment tester mon application express avec du moka?

Je viens d’ajouter shouldjs et mocha à mon application express pour les tests, mais je me demande comment tester mon application. Je voudrais le faire comme ça:

 app = require '../app'
routes = require '../src/routes'

describe 'routes', ->
  describe '#show_create_user_screen', ->
    it 'should be a function', ->
      routes.show_create_user_screen.should.be.a.function
    it 'should return something cool', ->
      routes.show_create_user_screen().should.be.an.object
 

Bien sûr, le dernier test de cette suite de tests indique simplement à med que la fonction res.render (appelée dans show_create_user_screen) n’est pas définie, car le serveur n’est pas en cours d’exécution et la configuration n’a pas été effectuée. Je me demande donc comment les autres organisent leurs tests?

64voto

trouvé une solution de rechange dans connect.js les tests de suites

Ils sont à l'aide de supertest pour tester une app connect sans liaison au serveur de n'importe quel port et sans l'aide de maquettes.

Voici un extrait de connecter statique du middleware de la suite de test (à l'aide de moka le test runner et supertest pour les assertions)

var connect = require('connect');

var app = connect();
app.use(connect.static(staticDirPath));

describe('connect.static()', function(){
  it('should serve static files', function(done){
    app.request()
    .get('/todo.txt')
    .expect('contents', done);
  })
});

Cela fonctionne pour exprimer les applications

32voto

Peter Lyons Points 47794

OK, d'abord, bien que le test de votre code de routage est quelque chose que vous pouvez ou ne voulez pas le faire, en général, essayez de séparer vos affaires intéressant la logique pure de code javascript (classes ou fonctions) qui sont découplées de l'express ou tout ce framework que vous utilisez et de l'utilisation de la vanille moka tests pour le tester. Une fois que vous avez réalisé que si vous voulez vraiment tester les itinéraires que vous configurez dans le moka, vous devez passer maquette req, res paramètres dans votre middleware de fonctions pour imiter l'interface entre l'express/connect et votre middleware.

Pour un cas simple, vous pouvez créer une maquette res objet avec un render fonction qui ressemble à quelque chose comme ça.

describe 'routes', ->
  describe '#show_create_user_screen', ->
    it 'should be a function', ->
      routes.show_create_user_screen.should.be.a.function
    it 'should return something cool', ->
      mockReq = null
      mockRes =
        render: (viewName) ->
          viewName.should.exist
          viewName.should.match /createuser/

      routes.show_create_user_screen(mockReq, mockRes).should.be.an.object

Aussi juste pour info middleware fonctions n'avez pas besoin de retourner une valeur particulière, c'est ce qu'ils font avec l' req, res, next paramètres que vous devriez vous concentrer sur le test.

Voici une partie du code JavaScript comme vous l'avez demandé dans les commentaires.

describe('routes', function() {
    describe('#show_create_user_screen', function() {
      it('should be a function', function() {
        routes.show_create_user_screen.should.be.a["function"];
      });
      it('should return something cool', function() {
        var mockReq = null;
        var mockRes = {
          render: function(viewName) {
            viewName.should.exist;
            viewName.should.match(/createuser/);
          }
        };
        routes.show_create_user_screen(mockReq, mockRes);
      });
    });
  });

21voto

LeeGee Points 833

Vous pouvez essayer SuperTest, puis le démarrage et l’arrêt du serveur sont pris en charge:

 var request = require('supertest')
  , app     = require('./anExpressServer').app
  , assert  = require("assert");

describe('POST /', function(){
  it('should fail bad img_uri', function(done){
    request(app)
        .post('/')
        .send({
            'img_uri' : 'foobar'
        })
        .expect(500)
        .end(function(err, res){
            done();
        })
  })
});
 

6voto

DeaDEnD Points 6890

le moka vient avec avant, avant, après, et après chaque pour le test de BDD. Dans ce cas, vous devez utiliser avant dans votre appel à décrire.

 describe 'routes' ->
  before (done) ->
    app.listen(3000)
    app.on('connection', done)
 

5voto

Bryan Donovan Points 41

J'ai trouvé qu'il était plus simple de configurer une classe TestServer à utiliser comme aide, ainsi que comme client HTTP d'aide, et de simplement envoyer de vraies requêtes à un vrai serveur http. Cependant, il peut arriver que vous souhaitiez vous moquer de ce genre de choses.

 // Test file
var http = require('the/below/code');

describe('my_controller', function() {
    var server;

    before(function() {
        var router = require('path/to/some/router');
        server = http.server.create(router);
        server.start();
    });

    after(function() {
        server.stop();
    });

    describe("GET /foo", function() {
        it('returns something', function(done) {
            http.client.get('/foo', function(err, res) {
                // assertions
                done();
            });
        });
    });
});


// Test helper file
var express    = require('express');
var http       = require('http');

// These could be args passed into TestServer, or settings from somewhere.
var TEST_HOST  = 'localhost';
var TEST_PORT  = 9876;

function TestServer(args) {
    var self = this;
    var express = require('express');
    self.router = args.router;
    self.server = express.createServer();
    self.server.use(express.bodyParser());
    self.server.use(self.router);
}

TestServer.prototype.start = function() {
    var self = this;
    if (self.server) {
        self.server.listen(TEST_PORT, TEST_HOST);
    } else {
        throw new Error('Server not found');
    }
};

TestServer.prototype.stop = function() {
    var self = this;
    self.server.close();
};

// you would likely want this in another file, and include similar 
// functions for post, put, delete, etc.
function http_get(host, port, url, cb) {
    var options = {
        host: host,
        port: port,
        path: url,
        method: 'GET'
    };
    var ret = false;
    var req = http.request(options, function(res) {
        var buffer = '';
        res.on('data', function(data) {
            buffer += data;
        });
        res.on('end',function(){
            cb(null,buffer);
        });
    });
    req.end();
    req.on('error', function(e) {
        if (!ret) {
            cb(e, null);
        }
    });
}

var client = {
    get: function(url, cb) {
        http_get(TEST_HOST, TEST_PORT, url, cb);
    }
};

var http = {
    server: {
        create: function(router) {
            return new TestServer({router: router});
        }
    },

    client: client
};
module.exports = http;
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X