Pergunta

Tenho um servidor https rodando via express, que testo usando mocha e supertest.

Meu problema é - se eu executar apenas o teste - tudo bem.Se eu tentar executar o gruntfile com teste, execute o expresso - vejo muitos erros EADDRINUSE, mesmo se em arquivos de teste eu fizer after() com app.close().O mesmo se aplica à observação de tarefas em testes.

Aqui está meu exemplo de teste:

/* jshint node: true*/
/*global describe, it, after*/
(function() {
    'use strict';
    process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
    var request = require('supertest');
    var app = require('../server.js').app;
    var expect = require('chai').expect;
    var Cookies;

    after(function(done) {
        app.close();
        setTimeout(function(){done();}, 1500);
    });

    describe('/login', function() {
        it('should auth the user', function(done) {
            request(app)
                .post('/login')
                .send({login: "test", password: 'test'})
                .expect(302)
                .end(function(err, res) {
                    expect(err).to.be.equal(null);
                    expect(res.text).to.be.equal("Moved Temporarily. Redirecting to /");
                    Cookies = res.headers['set-cookie'].pop().split(';')[0];
                    done();
            });

        });
    });
    // testing API for serving session data for angualar factory
    describe('/api/session', function() {
        it('should return session data in JSON', function(done) {
            var req = request(app).get('/api/session');             
                req.cookies = Cookies;
                req.set('Accept','application/json')
                .end(function(err, res) {
                    expect(err).to.be.equal(null);
                    expect(res.body).to.have.property("_id");
                    done();
            });
        });
    });

}());

Estou ciente de que esses testes estão longe de ser perfeitos.Estou apenas começando minha aventura com testes de software adequados.

Todas aquelas "portas já em uso" são óbvias, e nenhuma delas...dê qualquer problema.todos os testes funcionam bem, o servidor funciona bem, mas o stdout é uma loucura.Tal comportamento está longe de ser ideal e provavelmente cheio de potenciais problemas e questões de instabilidade.

Minha pergunta é: como se livrar disso?

Minhas ideias são:

  • crie um servidor dedicado para teste apenas em uma porta diferente.Infelizmente, tenho que saber como implementar isso.

  • faça alguma condicional para o superagente executar o servidor se ele não estiver em execução, ou apenas ...passá-lo para o superagente caso contrário?

  • use outra coisa que não o superagente (como request, mas não tenho certeza se todos os cookies e node_tls_reject_unauthorized funcionariam.

Como você pode ver, tenho dificuldade com esse tópico e tenho mais perguntas do que respostas, e não tenho experiência suficiente para saber onde procurar.

Agradeço qualquer ajuda.

EDITAR:

Eu descobri que posso fazer:

before(function(done) {
    app.listen(3001, function() { done(); });
});

que inicia o teste em outra porta, mas ...todo o server.js é carregado de qualquer maneira, então ele também inicia de qualquer maneira.Então, ao disparar junto com o servidor em execução, há EADDRINUSE óbvio.

Foi útil?

Solução

Ao usar superagent, você deve sempre passar para ele um aplicativo Express que foi configurado (middleware registrado, controladores roteados, etc.) - mas não inicializado como um servidor HTTP.Ele fará isso por você e adiará, através http.createServer, para o sistema operacional escolher uma porta disponível.

Se você atualmente tem isso server.js O módulo já está fornecendo uma instância estática de um servidor HTTP completo, que provavelmente é a origem dos seus problemas.Em ambos os casos, tente extrair a configuração/inicialização do aplicativo da instanciação real do servidor da seguinte forma:

// server.js
var express = require('express');
var middleware = require('./middleware');
var controllers = require('./controllers');

// Configures the Express application instance.
exports.setup = function (app) {
    app.use(middleware.foo);
    app.get('/bar', controllers.bar);

    app.locals.baz = 'quux';
}

// You might shoot yourself in the foot if parts of your application depend
// on a static reference at `server.app`.
exports.app = setup(express());
exports.app.listen(3000);

Então, em seus testes, você pode fazer algo como:

// tests.js
var express = require('express');
var server = require('./server');

describe('Server tests', function () {
    // Create a fresh server instance prior to each test
    beforeEach(function createNewSever() {
        this.app = server.setup(express());
    });

    describe('Foo', function () {
        it('barrs', function () {
            request(this.app)  // initializes a server instance on port A
            // ... supertests
        });

        it('bazzes', function () {
            request(this.app)  // initializes a server instance on port B
            // ... more supertests
        });
    });
});

Isso é apenas para fins ilustrativos, onde quando/como instanciar a instância do aplicativo dependerá do seu contexto de teste.O importante a ser aprendido é que você deve ser capaz de criar instâncias de servidor novas, limpas, independentes e isoladas para seus casos de teste.É uma necessidade absoluta se você usar um executor de testes que execute testes em paralelo ou em ordem aleatória.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top