nodeunit icon indicating copy to clipboard operation
nodeunit copied to clipboard

Should tearDown be queued on process.nextTick?

Open dfenster opened this issue 13 years ago • 0 comments

I've encountered an issue that's reproducible with async.parallel/auto and nodeunit.

var async = require('async');
var str;

exports.setUp = function(cb){
    console.log('setup');
    str = "This is a test";
    cb();
}

exports.tearDown = function(cb){
    //process.nextTick(function(){
        console.log('teardown');
        str = undefined;
        cb();
    //});
}

exports["testA"] = function(test){
    async.auto({
        test1:function(cb, results){
            console.log('test1');
            cb(new Error("test"));
        },
        test2:function(cb, results){
            console.log('test2');
            console.log(str, str.length);
            cb();
        }
    }, function(err, results){
        if(err) console.error(err);
        test.done();
    });
}

exports["testB"] = function(test){
    async.parallel({
        test1:function(cb, results){
            console.log('test1');
            cb(new Error("test"));
        },
        test2:function(cb, results){
            console.log('test2');
            console.log(str, str.length);
            cb();
        }
    }, function(err, results){
        if(err) console.error(err);
        test.done();
    });
}

This produces the output:

setup test1 [Error: test] teardown test2 teardown ✖ testA

TypeError: Cannot read property 'length' of undefined at Array.exports.testA.async.auto.test2 as 0 at async.auto (/Users/davefenster/node_modules/async/lib/async.js:406:38) at Array.forEach (native) at _forEach (/Users/davefenster/node_modules/async/lib/async.js:26:24) at Object.async.auto (/Users/davefenster/node_modules/async/lib/async.js:382:9) at Object.exports.testA (/Users/davefenster/temp/testnodeunitbug/test.js:19:8) at wrapTest (/Users/davefenster/node_modules/nodeunit/lib/core.js:231:20) at _asyncMap (/Users/davefenster/node_modules/nodeunit/deps/async.js:163:13) at async.forEachSeries.iterate (/Users/davefenster/node_modules/nodeunit/deps/async.js:126:25) at _asyncMap (/Users/davefenster/node_modules/nodeunit/deps/async.js:160:17)

setup test1 [Error: test] teardown test2 teardown ✖ testA

TypeError: Cannot read property 'length' of undefined at Array.exports.testA.async.auto.test2 as 0 at async.auto (/Users/davefenster/node_modules/async/lib/async.js:406:38) at Array.forEach (native) at _forEach (/Users/davefenster/node_modules/async/lib/async.js:26:24) at Object.async.auto (/Users/davefenster/node_modules/async/lib/async.js:382:9) at Object.exports.testA (/Users/davefenster/temp/testnodeunitbug/test.js:19:8) at wrapTest (/Users/davefenster/node_modules/nodeunit/lib/core.js:231:20) at _asyncMap (/Users/davefenster/node_modules/nodeunit/deps/async.js:163:13) at async.forEachSeries.iterate (/Users/davefenster/node_modules/nodeunit/deps/async.js:126:25) at _asyncMap (/Users/davefenster/node_modules/nodeunit/deps/async.js:160:17)

FAILURES: 2/2 assertions failed (12ms)

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

  • testB

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

The error manifests itself because tearDown runs before all the async.auto and async.parallel functions have executed. Ideally, what I'd want is the tearDown to run only after async.auto/parallel are complete. To make the tests pass, uncomment the process.nextTick line in the tearDown function.

Should nodeunit be putting tearDown on the nextTick queue all the time?

dfenster avatar Jan 07 '13 22:01 dfenster