Skip to content

Instantly share code, notes, and snippets.

@virtualandy
Last active August 29, 2015 14:05
Show Gist options
  • Save virtualandy/8e3665068469524357f7 to your computer and use it in GitHub Desktop.
Save virtualandy/8e3665068469524357f7 to your computer and use it in GitHub Desktop.
"use strict";
var chai = require("chai");
var sinon = require("sinon");
var sinonChai = require("sinon-chai");
chai.should();
chai.use(sinonChai);
function asyncHello(name, delay, cb) {
setTimeout(function() {
console.log("running after ", delay);
cb("hello " + name);
}, delay);
}
suite('Mega Suite', function(){
suite("testing async hello", function() {
test('should call the callback', function(done) {
var cb = sinon.spy();
asyncHello("foo", 500, cb);
cb.should.have.been.called();
done();
});
});
});
$ cat package.json
{
"name": "mocha-meetup",
"version": "0.0.0",
"description": "",
"main": "index.js",
"author": "",
"license": "ISC",
"devDependencies": {
"chai": "^1.9.1",
"mocha": "^1.21.4",
"sinon": "^1.10.3",
"sinon-chai": "^2.5.0"
},
"scripts": {
"test": "node_modules/.bin/mocha --ui=tdd test/*.js"
}
}
@virtualandy
Copy link
Author

Ken Powers has a great writeup on some of Sinon's advance features. I guess one approach is to use fake timers and skip using Mocha's done() functionality.

Based on that blog, I tweaked the test to look like:

suite('Mega Suite', function(){

  suite("testing async hello", function() {
    beforeEach(function () {
      // Overwrite the global timer functions (setTimeout, setInterval) with Sinon fakes
      this.clock = sinon.useFakeTimers();
    });

    afterEach(function () {
      // Restore the global timer functions to their native implementations
      this.clock.restore();
    });

    test('should call the callback', function() {
      var spy = sinon.spy();

      function asyncHello(name, delay, cb) {
        setTimeout(function() {
          console.log("running after ", delay);
          cb("hello " + name);
        }, delay);
      }

      asyncHello("foo", 1000, spy);
      this.clock.tick(999);
      spy.should.have.not.been.called;

      this.clock.tick(1);
      // Now the spy should have been called
      spy.should.have.been.called;

      spy.should.have.been.calledOnce;
    });
  });
});

Which works. Using done seems cleaner/simpler, though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment