Frage

Der Versuch, mit Node.js und NodeUnit auf dem neuesten Stand zu gehen, finde aber ein Problem mit NodeUnit, an dem er den Anruf nicht sieht test.done() in einem der Tests.

Der Code:

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

Ausgabe:

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

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

Ich hoffe, es ist etwas Dummes.

Versionen:-

Node: 0.10.21
NPM: 1.3.11
Nodeunit: 0.8.2
Grunt-CLI: 0.1.10
Grunt: 0.4.1
War es hilfreich?

Lösung

Erstens weiß ich nicht, welcher "Server" in Ihrem Code ist, aber ich würde erwarten, dass es asynchron ist, um so etwas in Ihrer Setup -Funktion zu haben:

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

Zweitens halten Sie diese Knoteneinheit anwesend führt das Start- und Ablagerungsfunktionen nach und vor jedem Test aus Ich vermute also, dass Sie Ihren Server 2 Mal starten (wie in der Abreißung, dass Sie ihn nicht wirklich schließen).

Andere Tipps

Ich habe die letzten Stunden damit verbracht, dieses Problem zu vermeiden, und es ist klar geworden, dass NodeUnit keine Möglichkeit hat, Ausnahmen zu fangen und anzuzeigen, die in Funktionen geworfen werden, die später von einem IO- oder SetTimeout -Prozess ausgelöst werden. In Anbetracht der Art und Weise, wie JavaScript ausgeführt wird, ist dies nicht überraschend. Alles funktioniert, sobald Sie sicher sind, dass es keine Ausnahmen gibt, aber wenn Sie einen Fehler in Ihrem Code haben, erhalten Sie "rückgängige Tests" -Botschaften und sonst nichts. Hier ist, was ich getan habe, um meine Probleme zu beheben (mit einem Beispiel mit einer Wiederherstellungsroute):

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

Sobald ich das Problem auf diese Weise verstanden habe und es behoben habe, weil ich viel klarer und ich konnte alle meine Tests bestehen!

Ich vermute, Sie rufen eigentlich nicht an test.done() In diesem zweiten Test. Leiten a console.log() Rufen Sie dort an, um zu überprüfen, ob Sie diesen Anruf tatsächlich tätigen.

FWIW, ich habe das beschriebene Problem unter Verwendung einer vereinfachten Version Ihres Tests im Folgenden wiedergegeben. Wenn Sie die weglassen on('error', function() {...}) Handler, dann kann der 2. Test nicht abgeschlossen werden. Meine Theorie ist also, dass Ihre /push Der Endpunkt löst ein anderes Verhalten im Wiederherstellungsmodul aus. Dh bist du sicher Wiederherstellung ruft Ihren Rückruf mit einem an err Eigentum dort oder macht es etwas anderes? ... wie zum Beispiel ein Ereignis wie wie http.get tut, unten.

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

Ich arbeite um ihn herum, indem ich den Server in den eigenen Prozess im Setup aufgreife und ihn dann im Ablagerungen tötet. Denken Sie, dass das Problem damit zu tun hat, dass der Server erstellt und nicht heruntergefahren wird. Danke @matteofigus dafür.

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();
        });
    }
};
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top