Pergunta

Tentando acelerar com node.js e nodeunidade, mas estou encontrando um problema com a nodeunidade onde não está vendo a chamada para test.done() em um dos testes.

O código:

// Added for clarity.
var client = require("restify").createJsonClient({
    "version": "*",
    "url": "http://localhost:" + server.Port
});

exports["tests"] = {
    "setUp": function (callback) {
        server.StartServer();
        callback();
    },
    "tearDown": function (callback) {
        callback();
    },
    "CanIHaveSomeTeaPlease?": function (test) {
        test.expect(4);
        client.get("/tea", function (err, req, res, data) {
            test.equal(err.statusCode, 418, "Expected ImATeapot Error.");
            test.equal(err.message, "Want a biscuit?", "Expected to be asked if I want a buscuit.");
            test.equal(err.restCode, "ImATeapotError");
            test.equal(err.name, "ImATeapotError");
            test.done();
        });
    },

    // Note: I expect this test to fail as it is a copy of the above
    //       test on a different url that doesn't return the ImATeapot
    //       HTTP error. But it doesn't look like it's detecting it
    //       properly.

    "TakeThisInfo": function (test) {
        test.expect(4);
        client.put("/push", {
            "hello": "world"
        }, function (err, req, res, data) {
            test.equal(err.statusCode, 418, "Expected ImATeapot Error.");
            test.equal(err.message, "Want a biscuit?", "Expected to be asked if I want a buscuit.");
            test.equal(err.restCode, "ImATeapotError");
            test.equal(err.name, "ImATeapotError");
            test.done();
        });
    }
};

Resultado:

FAILURES: Undone tests (or their setups/teardowns):
- tests - TakeThisInfo

To fix this, make sure all tests call test.done()

Espero que seja algo estúpido.

Versões:-

Node: 0.10.21
NPM: 1.3.11
Nodeunit: 0.8.2
Grunt-CLI: 0.1.10
Grunt: 0.4.1
Foi útil?

Solução

Primeiro, não sei o que "servidor" está em seu código, mas eu esperaria que seja assíncrono, para ter algo mais assim na sua função de configuração:

function (callback) {
  server.StartServer(function(){
    callback();
  });
}

Segundo, continue presente essa nodeunidade executa a startup e a desmontagem funciona depois e antes de cada teste Então, suspeito que você esteja iniciando seu servidor duas vezes (como na desmontagem, você não está realmente fechando).

Outras dicas

Passei as últimas duas horas mexendo com esse problema, e o que ficou claro é que a Nodeunit não tem capacidade de capturar e exibir exceções lançadas em funções que são acionadas posteriormente por um processo do tipo IO ou Settimeout. Considerando a maneira como o JavaScript funciona, isso não é surpreendente. Tudo funciona quando você tiver certeza de que não há exceções, mas se você tiver um erro no seu código, receberá uma mensagem "desfeita" e nada mais. Aqui está o que fiz para resolver meus problemas (usando uma rota Restify como exemplo):

function myRoute(req, res, next) {
    try {
        // your code goes here...
    }
    catch (err) {
        // write it to the console (for unit testing)
        console.log(err);
        // pass the error to the next function.
        next(err);
    }
}

Depois que entendi o problema dessa maneira, consertando -o porque muito mais claro e consegui que todos os meus testes passem!

Eu suspeito que você não está realmente ligando test.done() Nesse segundo teste. Colocar uma console.log() Ligue lá para verificar você está realmente fazendo essa chamada.

FWIW, eu reproduzi o problema descrito usando uma versão simplificada do seu teste, abaixo. Se você omitir o on('error', function() {...}) Manipulador, então o 2º teste falha na conclusão. Assim, minha teoria é que o seu /push O endpoint está desencadeando um comportamento diferente no módulo Restify. Ou seja, você é claro Restify está invocando seu retorno de chamada com um err propriedade lá, ou está fazendo algo diferente? ... como, por exemplo, emitindo um evento como http.get abaixo.

var http = require('http');

exports.test1 = function (test) {
  test.expect(1);
  http.get({hostname: "www.broofa.com", path: "/"}, function (res) {
    test.equal(res.statusCode, 200, 'got 200');
    test.done();
  });
};

exports.test2 = function (test) {
  test.expect(1);
  http.get({hostname: "www.no-such-domain.com", path: "/"}, function (res) {
    test.equal(res.statusCode, 200, 'got 200');
    test.done();
  }).on('error', function() {
    // Comment line below out to repro the "Undone tests" error
    test.done();
  });
};

Estou trabalhando em torno disso, comprando o servidor em seu próprio processo na configuração e depois matando -o na desmontagem. Pense que o problema estava a ver com o servidor que estava sendo criado e não para o desligamento. Obrigado @matteofiguus por isso.

var cp = null; // child process
exports["tests"] = {
    "setUp": function (callback) {
        cp = fork("./lib/server.js", {"silent": true});
        callback();
    },
    "tearDown": function (callback) {
        cp.kill("SIGHUP");
        callback();
    },
    "CanIHaveSomeTeaPlease?": function (test) {
        test.expect(4);
        client.get("/tea", function (err, req, res, data) {
            test.equal(err.statusCode, 418, "Expected ImATeapot Error.");
            test.equal(err.message, "Want a biscuit?", "Expected to be asked if I want a buscuit.");
            test.equal(err.restCode, "ImATeapotError");
            test.equal(err.name, "ImATeapotError");
            test.done();
        });
    },
    "TakeThisInfo": function (test) {
        test.expect(1);
        client.put("/push", {
            "hello": "world"
        }, function (err, req, res, data) {
            test.ok(false);
            test.done();
        });
    }
};
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top