moin moin
moin moin

Reputation: 2453

learning nodeunit

I trying to bend my head around the async nature of node.js and nodeunit.

now nodeunit is supposed to help me out but it gives me headaches as well:

$ nodeunit test_logfile.js 

test_logfile.js
✖ testLogentry

Error: Expected 1 assertions, 0 ran
    at Object.done (/home/mark/.node_libraries/.npm/nodeunit/0.5.1/package/lib/types.js:119:25)
    at /home/mark/devel/PerfDriver/test/test_logfile.js:48:10
    at Object.runTest (/home/mark/.node_libraries/.npm/nodeunit/0.5.1/package/lib/core.js:54:9)
    at /home/mark/.node_libraries/.npm/nodeunit/0.5.1/package/lib/core.js:90:21
    at /home/mark/.node_libraries/.npm/nodeunit/0.5.1/package/deps/async.js:508:13
    at /home/mark/.node_libraries/.npm/nodeunit/0.5.1/package/deps/async.js:118:13
    at /home/mark/.node_libraries/.npm/nodeunit/0.5.1/package/deps/async.js:134:9
    at /home/mark/.node_libraries/.npm/nodeunit/0.5.1/package/deps/async.js:507:9
    at Object.concatSeries (/home/mark/.node_libraries/.npm/nodeunit/0.5.1/package/deps/async.js:147:23)
    at Object.runSuite (/home/mark/.node_libraries/.npm/nodeunit/0.5.1/package/lib/core.js:79:11)


FAILURES: 1/1 assertions failed (50ms)

node.js:116
        throw e; // process.nextTick error, or 'error' event on first tick
        ^
Error: ECONNREFUSED, Connection refused
    at Socket._onConnect (net.js:576:18)
    at IOWatcher.onWritable [as callback] (net.js:165:12)

here is my testcase:

var nodeunit = require('../lib/nodeunit/lib/nodeunit.js')
var http = require('http');
var logfile = require('../src/logfile.js');

var testmsg = 'this is my first testmessage:-_,.:;öüäß?1234"@€';


exports.testLogentry = function(test) {
    test.expect(1); // make sure all the async expectations are fulfilled

    var options = {
        host: 'localhost',
        port: 8123,
        path: '/',
        method: 'POST',
        record_message: function(msg) {
            console.log('received ' + msg + '\n');
            test.equal(msg, testmsg);
            return;
        }
    };

    var logger = logfile.loggerFactory(options);

    logfile.write(testmsg, options);
    logger.stop();
    test.done();
};

I guess my question is if assertions work well in callbacks or if there are any restrictions that might cause the testcase to fail. My assumption is that nodeunit is able to cope with the asynchronous programming style. So I expect "test.equal(msg, testmsg);" to work. If I run the content of the testcase in the node console then "record_message" is called. I would post logfile.js as well but this is probably to much and I am looking for more general advice.

Thanks.

Mark

Upvotes: 2

Views: 2770

Answers (2)

moin moin
moin moin

Reputation: 2453

I am not exactly sure how this is handled here generally but meanwhile I have found the solution to my problem and I post it here in case someone will struggle with the same issue.

Now I can tell that the problem has to do with the asynchronous character of node.js, http server and unit testing under these circumstances.

Anyways here is my solution:

var nodeunit = require('../lib/nodeunit/lib/nodeunit.js');
var http = require('http');
var logfile = require('../src/logfile');

var testmsg = 'this is my first testmessage:-_,.:;öüäß?1234"@€';


var testutil = function (config, envReady) {
    // simple testutil to provide http server environment for unit testing

    var logger = logfile.loggerFactory(config);

    // actually this is the tricky part which ensures that the server
    // is still available once request/ response are executed
    process.nextTick(function () {
        if (envReady && typeof envReady === 'function') {
            envReady(logger, logfile.write);
        }
    });
};


exports.test_logfile = function (test) {

    test.expect(4);

    var options = {
        host: 'localhost',
        port: 3000,
        path: '/simple',
        method: 'PUT',
        record_message: function(msg) {
            test.equal(msg, testmsg);
        }
    };

    testutil(options, function (logger, write) {
        var write_ready = function(res) {
            // called when write is completed
            test.equal(res.statusCode, 201);
            test.equal(res.headers['content-type'], 'text/plain');
            test.equal(res.body, 'created');

            logger.stop();
            test.done();
        };

        write(testmsg, options, write_ready);
    });
};

Upvotes: 2

moin moin
moin moin

Reputation: 2453

I think in the original version there are a few things wrong. After some hours of sleep I moved the logger.stop() and test.end() calls to the end of the record_message function. Now the assertion "passes" silently but the error is persistent.

$ nodeunit test_logfile.js 

test_logfile.js

node.js:116
    throw e; // process.nextTick error, or 'error' event on first tick
    ^
Error: ECONNREFUSED, Connection refused
at Socket._onConnect (net.js:576:18)
at IOWatcher.onWritable [as callback] (net.js:165:12)

Here is the nodeunit testcase in its current version:

var nodeunit = require('../lib/nodeunit/lib/nodeunit.js')
var http = require('http');
var logfile = require('../src/logfile.js');

var testmsg = 'this is my first testmessage:-_,.:;öüäß?1234"@€';


exports.testLogentry = function(test) {
    test.expect(1); // make sure all the async expectations are fulfilled

    var options = {
        host: 'localhost',
        port: 8123,
        path: '/',
        method: 'POST',
        record_message: function(msg) {
            console.log('received ' + msg + '\n');
            test.equal(msg, testmsg);

            logger.stop();
            setTimeout(test.done, 2000);
        }
    };

    var logger = logfile.loggerFactory(options);

    logfile.write(testmsg, options);
};

Upvotes: 0

Related Questions