Domanda

Cercando di alzarsi per accelerare con node.js e nodeunit ma sto trovando un problema con Nodeunit in cui non vede la chiamata a test.done() in uno dei test.

Il codice:

// 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();
        });
    }
};

Produzione:

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

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

Spero che sia qualcosa di stupido.

Versioni:-

Node: 0.10.21
NPM: 1.3.11
Nodeunit: 0.8.2
Grunt-CLI: 0.1.10
Grunt: 0.4.1
È stato utile?

Soluzione

Innanzitutto, non so cosa sia il "server" nel tuo codice, ma mi aspetto che sia asincrono, quindi avere qualcosa di più simile nella tua funzione di configurazione:

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

Secondo, tieni presente quel nodeunit esegue l'avvio e le funzioni di smontaggio dopo e prima di ogni test Quindi sospetto che tu stia iniziando il tuo server 2 volte (come nello smontaggio non lo stai chiudendo davvero).

Altri suggerimenti

Ho trascorso le ultime due ore a scherzare con questo problema e ciò che è diventato chiaro è che Nodeunit non ha la capacità di catturare e mostrare eccezioni lanciate in funzioni che vengono attivate in seguito da un processo di tipo IO o setTimeout. Considerando il modo in cui JavaScript funziona, questo non è sorprendente. Tutto funziona una volta che sei sicuro che non ci sono eccezioni, ma se hai un errore nel tuo codice, riceverai un messaggio di "test annullati" e nient'altro. Ecco cosa ho fatto per risolvere i miei problemi (usando un percorso di restituzione come esempio):

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);
    }
}

Una volta ho capito il problema in questo modo, risolvendolo perché molto più chiaro e sono stato in grado di far passare tutti i miei test!

Sospetto che in realtà non stai chiamando test.done() In quel secondo test. Mettere a console.log() Chiama lì per verificare che stai effettivamente effettuando quella chiamata.

FWIW, ho riprodotto il problema descritto usando una versione semplificata del test, di seguito. Se ometti il on('error', function() {...}) Handler, quindi il secondo test non riesce a completare. Quindi, la mia teoria è che la tua /push L'endpoint sta innescando un comportamento diverso nel modulo REDify. IE sei tu sicuro Restrify sta invocando il tuo callback con un err proprietà lì o sta facendo qualcosa di diverso? ... come, ad esempio, emettere un evento come http.get fa, di seguito.

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();
  });
};

Sto lavorando attorno a esso biforcando il server nel proprio processo nella configurazione e poi uccidendolo nello smontaggio. Pensa che il problema fosse a che fare con il server creato e non l'arresto. Grazie @matteofigus per questo.

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();
        });
    }
};
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top