سؤال

في محاولة للوصول إلى السرعة مع Node.js و NodeUnit ، لكنني أجد مشكلة مع NodeUnit حيث لا ترى المكالمة test.done() في أحد الاختبارات.

الرمز:

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

انتاج:

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

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

آمل أن يكون شيئًا غبيًا.

الإصدارات:-

Node: 0.10.21
NPM: 1.3.11
Nodeunit: 0.8.2
Grunt-CLI: 0.1.10
Grunt: 0.4.1
هل كانت مفيدة؟

المحلول

أولاً ، لا أعرف ما هو "الخادم" في الكود الخاص بك ، لكنني أتوقع أن يكون غير متزامن ، حتى يكون لديك شيء مثل هذا في وظيفة الإعداد الخاصة بك:

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

ثانياً ، حافظ على هذا العقد ينفذ بدء التشغيل ووظائف teardown بعد كل اختبار وقبله لذلك أظن أنك بدأت الخادم الخاص بك مرتين (كما في الدموع ، أنت لا تغلقه حقًا).

نصائح أخرى

لقد قضيت الساعتين الأخيرين في العبث بهذه المشكلة ، وما أصبح واضحًا هو أن Nodeunit ليس لديه القدرة على التقاط واستثناءات عرضها في الوظائف التي يتم تشغيلها لاحقًا بواسطة عملية io أو setTimeout type. بالنظر إلى الطريقة التي يدير بها جافا سكريبت ، هذا ليس مفاجئًا. كل شيء يعمل بمجرد أن تكون متأكدًا من عدم وجود استثناءات ، ولكن إذا كان لديك خطأ في التعليمات البرمجية الخاصة بك ، فستحصل على رسالة "تم تراجع الاختبارات" ولا شيء آخر. إليكم ما فعلته لحل مشاكلي (باستخدام مسار إعادة توحيد كمثال):

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

بمجرد أن فهمت المشكلة بهذه الطريقة ، قم بإصلاحها لأن الكثير وضوحًا وكنت قادرًا على الحصول على جميع اختباراتي لتمريرها!

أظن أنك لا تتصل بالفعل test.done() في هذا الاختبار الثاني. ضع console.log() اتصل هناك للتحقق من أنك تجري هذه المكالمة بالفعل.

FWIW ، لقد قمت بإعادة صياغة المشكلة الموصوفة باستخدام نسخة مبسطة من الاختبار الخاص بك أدناه. إذا حذفت on('error', function() {...}) معالج ، ثم فشل الاختبار الثاني في إكماله. وبالتالي ، نظريتي هي أن /push نقطة النهاية تؤدي إلى سلوك مختلف في وحدة إعادة الترجيح. أي هل أنت بالتأكيد إعادة التثبيت هو استدعاء رد الاتصال الخاص بك مع err الممتلكات هناك ، أم أنها تفعل شيئًا مختلفًا؟ ... مثل ، على سبيل المثال ، انبعاث حدث مثل http.get لا ، أدناه.

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

أنا أعمل حوله عن طريق نقل الخادم في عملية خاصة به في الإعداد ثم قتله في المسيل للدموع. أعتقد أن المشكلة كانت تتعلق بالخادم الذي يتم إنشاؤه وليس الإغلاق. شكرا matteofigus لذلك.

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();
        });
    }
};
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top