The idea that you write tests first, then you write code.
As a result, you think about how you will use the code before you implement it.
assert(isEven(2), true)
function isEven(n) {
return n % 2 === 0;
}
FAIL
PASS
Unit tests should be specific, and so should the code to make the test pass.
Once it passes, refactor, and move on to the next test.
Mocha is a feature-rich JavaScript testing framework that runs on both the browser and Node.
var assert = require("assert");
describe('Array', function(){
describe('#indexOf()', function(){
it('should return -1 when the value is not present', function(){
assert.equal(-1, [1,2,3].indexOf(5));
assert.equal(-1, [1,2,3].indexOf(0));
})
})
})
Mocha offers developers different domain specific languages (DSLs) for writing tests.
describe('Array', function(){
before(function(){
// ...
});
describe('#indexOf()', function(){
it('should return -1 when not present', function(){
[1,2,3].indexOf(4).should.equal(-1);
});
});
});
suite('Array', function(){
setup(function(){
// ...
});
suite('#indexOf()', function(){
test('should return -1 when not present', function(){
assert.equal(-1, [1,2,3].indexOf(4));
});
});
});
module.exports = {
before: function(){
// ...
},
'Array': {
'#indexOf()': {
'should return -1 when not present': function(){
[1,2,3].indexOf(4).should.equal(-1);
}
}
}
};
function ok(expr, msg) {
if (!expr) throw new Error(msg);
}
suite('Array');
test('#length', function(){
var arr = [1,2,3];
ok(arr.length == 3);
});
test('#indexOf()', function(){
var arr = [1,2,3];
ok(arr.indexOf(1) == 0);
ok(arr.indexOf(2) == 1);
ok(arr.indexOf(3) == 2);
});
suite('String');
test('#length', function(){
ok('foo'.length == 3);
});
var testCase = require('mocha').describe
var pre = require('mocha').before
var assertions = require('mocha').assertions
var assert = require('assert')
testCase('Array', function(){
pre(function(){
// ...
});
testCase('#indexOf()', function(){
assertions('should return -1 when not present', function(){
assert.equal([1,2,3].indexOf(4), -1);
});
});
});
Mocha makes it simple to test your asynchronous code using a done() callback function.
it('should save without error', function(done){
var user = new User('Luna');
user.save(function(err){
if (err) throw err;
done();
});
})
it('should save without error', function(done){
var user = new User('Luna');
user.save(done);
})
To make things easier the done() callback accepts an error:
Automatically runs tests whenever a file is changed.
$ mocha -w
Mocha keeps track of which lines of code have been tested, which other libraries can access.
An assertion library for node and the browser that can be paired with any JavaScript testing framework.
Provides many plugins for testing your code, including:
Extends each object with a should property to start your assertion chain.
var foo = 'bar',
beverages = {tea: [ 'chai', 'matcha', 'oolong']};
foo.should.be.a('string');
foo.should.equal('bar');
foo.should.have.length(3);
tea.should.have.property('flavors').with.length(3);
Extends each object with a should property to start your assertion chain.
var foo = 'bar',
beverages = {tea: [ 'chai', 'matcha', 'oolong']};
expect(foo).to.be.a('string');
expect(foo).to.equal('bar');
expect(foo).to.have.length(3);
expect(beverages).to.have.property('tea').with.length(3);
// AssertionError: topic [answer]: expected 43 to equal 42.
expect(answer, 'topic [answer]').to.equal(42);
var value = undefined;
expect(value).to.be.undefined;
classic assert-dot notation, similiar to that packaged with node.js. This assert module, however, provides several additional tests and is browser compatible.
var foo = 'bar',
beverages = {tea: [ 'chai', 'matcha', 'oolong']};
assert.typeOf(foo, 'string', 'foo is a string');
assert.equal(foo, 'bar', 'foo equal `bar`');
assert.lengthOf(foo, 3, 'foo`s value has a length of 3');
assert.lengthOf(beverages.tea, 3, 'beverages has 3 types of tea');
Standalone test spies, stubs, and mocks for JavaScript.
Spies
Stubs
Fake XML/HTTP Requests
and more
Allow you to check the conditions surrounding how a function was invoked.
it("calls the original function", function () {
var callback = sinon.spy();
var proxy = once(callback);
proxy();
assert(callback.called);
});
Test stubs are functions (spies) with pre-programmed behavior.
it("returns the return value from the original function", function () {
var returnsFourtyTwo = sinon.stub().returns(42);
assert.equals(returnsFourtyTwo(), 42);
});
function getTodos(listId, callback) {
jQuery.ajax({
url: "/todo/" + listId + "/items",
success: function (data) {
// Node-style CPS: callback(err, data)
callback(null, data);
}
});
}
after(function () {
// When the test either fails or passes, restore the original
// jQuery ajax function (Sinon.JS also provides tools to help
// test frameworks automate clean-up like this)
jQuery.ajax.restore();
});
it("makes a GET request for todo items", function () {
sinon.stub(jQuery, "ajax");
getTodos(42, sinon.spy());
assert(jQuery.ajax.calledWithMatch({ url: "/todo/42/items" }));
});
var xhr, requests;
before(function () {
xhr = sinon.useFakeXMLHttpRequest();
requests = [];
xhr.onCreate = function (req) { requests.push(req); };
});
after(function () {
// Like before we must clean up when tampering with globals.
xhr.restore();
});
it("makes a GET request for todo items", function () {
getTodos(42, sinon.spy());
assert.equals(requests.length, 1);
assert.match(requests[0].url, "/todo/42/items");
});