Evan Shortiss
Software Engineer and Mobile Developer. Works at FeedHenry
$npm install -g mocha
or
$npm install -g jasmine
'use strict';
var drinks = require('drinks'); // or window.drinks in a browser
describe('Drinks Module', function () {
describe('#getSomethingStrong', function () {
it('Should return "whiskey"', function () {
var res = drinks.getSomethingStrong();
expect(res).toEqual('whiskey');
});
});
describe('#getLemonade', function () {
it('Should return lemonade', function () {
var res = drinks.getSomethingStrong();
expect(res).toEqual('lemonade');
});
});
})
Choosing is primarily a matter of preference
$npm install chai --save-dev
'use strict';
var drinks = require('drinks'), // or window.drinks (depending on environment)
chai = require('chai'), // or window.chai
assert = chai.assert,
expect = chai.expect;
describe('Drinks Module', function () {
describe('#getCheapBeer', function () {
it('Should return a cheap, nasty beer', function () {
var beer = drinks.getCheapBeer();
expect(beer).to.be.defined;
expect(beer).to.be.a('string');
expect(beer.toLowerCase()).to.equal('ducth gold');
});
});
});
'use strict';
var drinks = require('drinks'),
chai = require('chai'),
assert = chai.assert,
expect = chai.expect;
describe('Drinks Module', function () {
describe('#getCheapBeer', function () {
it('Should return a cheap, nasty beer', function () {
var beer = drinks.getCheapBeer();
assert.notEqual(typeof beer, 'undefined');
assert.equal(typeof beer ,'string');
assert.equal(beer.toLowerCase(), 'ducth gold');
});
});
});
$npm install browserify testling
"testling": {
"harness": "mocha-bdd",
"files": "test/*.js",
"browsers": [
"ie/8..latest",
"chrome/22..latest",
"firefox/16..latest",
"safari/4..latest",
"opera/11.0..latest",
"iphone/6..latest",
"ipad/6..latest",
"android-browser/latest"
]
}
$npm install -g karma
module.exports = function(config) {
config.set({
frameworks: ['mocha', 'chai'],
files: [
// Put Mocha/Jasmine tests here
'./test/moduleA.js'
],
reporters: ['mocha'],
port: 9876,
colors: true,
logLevel: 'INFO',
captureTimeout: 60000,
autoWatch: false,
browsers: ['Chrome', 'Safari', 'Firefox'],
singleRun: true
});
};
$karma start
mocha init path/to/testdir
'use strict';
describe('Number Service', function () {
var Numbers;
// Create an app instance "module" comes from Angular mocks
// 'myApp' is the name of our angular.module instance our code creates
beforeEach(module('myApp'));
// Get a new Service instance ,"inject" comes from Angular mocks
beforeEach(inject(function (_Numbers_) {
Numbers = _Numbers_;
}));
describe('#getInRange', function () {
it('Should get number in range specified', function () {
var n = Numbers.getInRange(10, 90);
expect(n).to.be.a('number');
expect(n).to.be.within(10, 90);
});
});
});
describe('Number Service', function () {
var Numbers;
beforeEach(module('myApp'));
beforeEach(inject(function (_Numbers_) {
Numbers = _Numbers_;
}));
describe('#getInRangeAsync', function () {
it('Should get number in range specified', function (done) {
Numbers.getInRangeAsync(10, 9).then(function (n) {
expect(er).to.be.null;
expect(n).to.be.a('number');
expect(n).to.be.within(10, 90);
done();
}, done); // Done, when passed an arg, marks the test as failed
}); // so we can pass done as the error callback even if we a
}); // aren't expecting an error.
});
Do we need a Server?
* If using promises this may not work. You will still need to test asynchronously.
App.Controllers.Auth = (function ($fh) {
var session = null;
this.login = function (username, password, callback) {
$fh.act({
act: 'login',
req: { u: username, p: password }
}, function (res) {
if (res.session) {
session = res.session;
callback(null, true);
} else {
// Invalid user/pass etc...
callback(null, false);
}
}, callback); // <--- Being lazy!
};
this.isLoggedIn = function () {
return (session !== null);
};
return this;
})(window.$fh);;
describe('Auth', function () {
var VALID = { u: 'bruce.w', p: 'iamthebatman' };
describe('#login', function () {
it('Should not return an error', function () {
// The magic beings...
$fh.act.expect({
act: 'login',
req: VALID
}).setResponse(null, {
session: 'SOME_RANDOM_SESSION_KEY'
});
// This will trigger the Act call we just set an expectation for!
App.Controllers.Auth.login(VALID.u, VALID.p, function (err, loggedIn) {
expect(err).to.be.null;
expect(loggedIn).to.equal(true);
});
// Respond to any queued Act calls (like the one above via Auth)
$fh.act.flush();
});
});
});
angular.module('myApp', [
'ng',
'ngFH' // <-- Awesomesauce
]);
angular.module('myApp').service('Auth', function ($scope, $q, Act) {
// Other code...
$scope.checkLogin = function (u, p) {
// Act.request returns a promise
return Act.request({
act: 'login' ,
req: {
u: u,
p: p
}
});
};
});
angular.module('myApp').controller('LoginPage', function () {
// Other code...
$scope.doLogin = function () {
Auth.checkLogin($scope.form.username, $scope.form.password)
.then(successFn, failFn);
};
});
By Evan Shortiss
An introduction to unit testing for JavaScript applications running on a client or server (Node.js) These slides cover, Mocha/Jasmine, Chai, Karma, AngularJS and FeedHenry testing practices.
Software Engineer and Mobile Developer. Works at FeedHenry