Skip to content

Instantly share code, notes, and snippets.

@glenjamin
Last active August 29, 2015 13:56
Show Gist options
  • Save glenjamin/9142187 to your computer and use it in GitHub Desktop.
Save glenjamin/9142187 to your computer and use it in GitHub Desktop.
The most Rspec-like mocha test I've managed to write so far
// The single letter variables are designed to be invisible
// Yes, there are a few global variables: t, s and expect
// The system under test has no globals, so I can't conflict!
var h = require('../spec-helper.js');
var command = require('../../lib/command-round-init.js');
describe('Command: round-init', function() {
beforeEach(function() {
t.calcLog = h.stubCalculationLog();
t.round = 22;
})
function runCommand(done) {
t.callback = s.spy(function() { done() })
command({db: t.db, log: t.log}, t.timer, t.round, t.callback);
}
function shouldBehaveLikeCommand() {
it('should start calculation log with info', function() {
expect(t.calcLog.wrap).to.be.calledOnce
expect(t.calcLog.wrap).to.be.calledWith(
t.db, t.log, 'round-init', 22)
expect(t.calcLog.wrap).to.be.calledBefore(t.db.query)
})
it('should run SQL with round id', function() {
expect(t.db.query).to.be.calledOnce
expect(t.db.query).to.be.calledWithMatch("INSERT IGNORE", [22])
})
it('should log SQL and params', function() {
expect(t.log.info).to.be.calledWithMatch(
"SQL:", [t.db.query.firstCall.args[0], 22])
})
it('should end calculation log after query', function() {
expect(t.calcLog.callback).to.be.calledOnce
expect(t.calcLog.callback).to.be.calledAfter(t.db.query)
})
}
context('successful query', function() {
beforeEach(function() { t.db.query.yieldsAsync() })
beforeEach(runCommand)
shouldBehaveLikeCommand()
it('should callback once complete', function() {
expect(t.callback).to.be.calledOnce
})
})
context('failed query', function() {
beforeEach(function() { t.db.query.yieldsAsync(new Error('failed')) })
beforeEach(runCommand)
shouldBehaveLikeCommand()
it('should callback with error', function() {
expect(t.callback).to.be.calledOnce
expect(t.callback).to.be.calledWith(s.match(Error))
})
})
})
// tel, chai, sinon and sinon-chai all stock installs from npm
var Tel = require('tel');
var chai = require('chai');
global.expect = chai.expect;
var sinon = require('sinon');
chai.use(require('sinon-chai'));
beforeEach(function() {
global.s = sinon.sandbox.create();
s.match = sinon.match;
global.t = Tel();
t.db = {
query: s.stub()
};
t.log = {
debug: s.stub(),
info: s.stub(),
notice: s.stub(),
warn: s.stub(),
error: s.stub()
};
t.callback = s.spy();
});
afterEach(function() {
s.restore();
})
// You'll have to take my word for it that this does something vaguely sensible.
var calcLog = require('../lib/calculation-log');
exports.stubCalculationLog = function stubCalculationLog() {
var stubbedCalcLog = {};
s.stub(calcLog, 'wrap', fakeCalcWrap);
function fakeCalcWrap(/*..., callback, body*/) {
var args = arguments.length;
stubbedCalcLog.callback = s.spy(arguments[args - 2]);
arguments[args - 1](stubbedCalcLog.callback);
}
stubbedCalcLog.wrap = calcLog.wrap;
return stubbedCalcLog;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment