Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

async.waterfall is not working with Sinon.JS fake timers in Node.js #106

Closed
rstuven opened this issue Feb 27, 2012 · 4 comments
Closed

async.waterfall is not working with Sinon.JS fake timers in Node.js #106

rstuven opened this issue Feb 27, 2012 · 4 comments

Comments

@rstuven
Copy link

rstuven commented Feb 27, 2012

Using async.series, the following example works just fine.

var async = require("async");
var sinon = require("sinon");

var clock = sinon.useFakeTimers();

async.series([
    function fn1(cb) {
        console.log("fn1");
        setTimeout(function(){
            cb();
        }, 100);
    },
    function fn2(cb) {
        console.log("fn2");
        cb();
    }
]);

clock.tick(1000);

But if we change async.series by async.waterfall, the program exits before fn2 is called.

var async = require("async");
var sinon = require("sinon");

var clock = sinon.useFakeTimers();

async.waterfall([
    function fn1(cb) {
        console.log("fn1");
        setTimeout(function(){
            cb();
        }, 100);
    },
    function fn2(cb) {
        console.log("fn2");
        cb();
    }
]);

clock.tick(1000);

UPDATE: In the browser, async.waterfall works fine.

<script type="text/javascript" src="http://sinonjs.org/releases/sinon-1.3.1.js"></script>
<script type="text/javascript" src="https://raw.github.com/caolan/async/master/dist/async.min.js"></script>
<script type="text/javascript">

var clock = sinon.useFakeTimers();

async.waterfall([
    function fn1(cb) {
        console.log("fn1");
        setTimeout(function(){
            cb();
        }, 100);
    },
    function fn2(cb) {
        console.log("fn2");
        cb();
    }
]);

clock.tick(1000);

</script>
@rstuven
Copy link
Author

rstuven commented Feb 27, 2012

async.auto works fine in Node.js too:

var async = require("async");
var sinon = require("sinon");

var clock = sinon.useFakeTimers();

async.auto({
    "f2": ["f1", function f2(cb) {
        console.log("fn2");
        cb();
    }],
    "f1": function f1(cb) {
        console.log("fn1");
        setTimeout(function(){
            cb();
        }, 100);
    }
});

clock.tick(1000);

@rstuven
Copy link
Author

rstuven commented Feb 27, 2012

I found the source of the issue and a way to "patch" async so it works nicely with Sinon.JS:

if (typeof sinon === "object" && typeof sinon.timers === "object") {
    (function(){
        var nextTick = async.nextTick;
        async.nextTick = function(fn) {
            if (global.setTimeout === sinon.timers.setTimeout)
                nextTick(fn);
            else
                global.setTimeout(fn, 0);
        };
    })();
}

@statico
Copy link

statico commented Dec 20, 2012

You're not crazy. We had to do something similar when using fake timers, too.

@eloone
Copy link

eloone commented Nov 17, 2014

If you only need to fake the date you can do sinon.useFakeTimers('Date'), it will work since the problem with async.waterfall comes from sinon faking setIntermediate see #609. Read the useFakeTimers doc to only fake the method you want to fake.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants