Installation
For Node.js
You can install Unit.js with NPM (Node Package Manager).
npm install unit.js
For the browser
Although originally designed for use with Node.js, it can also be used directly in the browser.
Usage
Create test
directory and create a file named example.js
in the test
directory.
path/your/project/test/example.js
Write this below code in the example.js
file :
// load Unit.js module
var test = require('unit.js');
// just for example of tested value
var example = 'hello';
// assert that example variable is a string
test.string(example);
// or with Must.js
test.must(example).be.a.string();
// or with assert
test.assert(typeof example === 'string');
Run the tests with Mocha (or other runner)
mocha test/example.js
example.js
is tested :)
OR locally
./node_modules/mocha/bin/mocha test/example.js
Display the spec report with -R spec
mocha test/example.js -R spec
You can launch the tests for all files in the test
directory
mocha test -R spec --recursive
See also the Mocha tutorial.
Example (proposal) of structured unit tests suite
var test = require('unit.js');
describe('Learning by the example', function(){
it('example variable', function(){
// just for example of tested value
var example = 'hello world';
test
.string(example)
.startsWith('hello')
.match(/[a-z]/)
.given(example = 'you are welcome')
.string(example)
.endsWith('welcome')
.contains('you')
.when('"example" becomes an object', function(){
example = {
message: 'hello world',
name: 'Nico',
job: 'developper',
from: 'France'
};
})
.then('test the "example" object', function(){
test
.object(example)
.hasValue('developper')
.hasProperty('name')
.hasProperty('from', 'France')
.contains({message: 'hello world'})
;
})
.if(example = 'bad value')
.error(function(){
example.badMethod();
})
;
});
it('other test case', function(){
// other tests ...
});
});
Result
Migrating to Unit.js
Unit.js should work with any framework (and runner) unit tests. I tested Unit.js with Mocha and Jasmine, it works very well with these two runners.
For use Unit.js in an existing tests suite, you can write your new tests with Unit.js in your new files of unit tests.
For use Unit.js in an existing file of unit tests, you just have to load it with require('unit.js')
and use it like any assertion lib, example:
var test = require('unit.js');
// your old tests with your old assertion lib
// and your new tests with Unit.js
Remember
var test = require('unit.js');
Asserter
Asserter = value(), number(), object(), function(), array(), exception(), ...
The value asserter is the generic asserter (works with all types of value), all assertions are listed in the value asserter.
Except the value asserter that is generic, each asserter is conditioned to work with a value type (string, number, array, object, exception, error instance, function, Date instance, RegExp instance ...).
The asserters are listed on the right column of all pages of UnitJS.com for quick access.
Usage:
test.value(val);
test.object(val);
test.string(val);
test.number(val);
test.exception(function() {
// this function is triggered
// to test whether an exception is thrown
});
test.error(function() {
// this function is triggered
// to test whether an exception is thrown and is an instance of Error
});
test.date(val);
// ...
Assertion
Assertion = isEqualTo(), isIdenticalTo(), match(), contains(), isString, isType(), is(), ...
All assertions are listed in the value asserter.
test.value(val).isEqualTo('expected value');
API doc
The API doc is the technical documentation of each asserters (methods signatures, description, examples, ...).
Spec doc
The spec doc describe each asserter with the examples of behavior for all asserters and assertions.
helpers
dump the actual tested value
test.dump();
dump given values
test.dump(val1, val2, val3);
Stats
test.dump(test.stats);
execute a given function after n milliseconds
test.wait(50, fn);
expressive helpers
test.case();
test.if();
test.and();
test.given();
test.when();
test.then();
See also: helpers
dependency injection
test.$di.set('sayHello', function(name) {
return 'Hello ' + name;
});
test
.case(function() {
// returns: 'Hello Nico'
this.sayHello('Nico');
})
.if(function() {
// returns: 'Hello Nico'
this.sayHello('Nico');
})
.and(function() {
// returns: 'Hello Nico'
this.sayHello('Nico');
})
.given(function() {
// returns: 'Hello Nico'
this.sayHello('Nico');
})
.when(function() {
// returns: 'Hello Nico'
this.sayHello('Nico');
})
.then(function() {
// returns: 'Hello Nico'
this.sayHello('Nico');
})
.wait(20, function() {
// returns: 'Hello Nico'
this.sayHello('Nico');
})
.exception(function() {
// returns: 'Hello Nico'
this.sayHello('Nico');
})
.error(function() {
// returns: 'Hello Nico'
this.sayHello('Nico');
})
;
See also: Dependency Injection
API and styles
test.assert()
test.should()
test.must()
test.sinon
Mocks (Sinon.js)
test.mock
Stubs (Sinon.js)
test.stub
Spy (Sinon.js)
test.spy
Faking timers (Sinon.js)
test.fakeTimers
test.httpAgent();
Asynchronous tests
Async (done
) with Mocha, Jasmine and other runners:
it('blabla', function(done) {
// ...
done();
});
Promise:
test.promise
.given(asyncFunction)
.then(function(value) {
// ...
})
.catch(function(err){
test.fail(err.message);
})
.done()
;
Promise with done
callback:
it('blabla', function(done) {
test.promise
.given(asyncFunction)
.then(function(value) {
// ...
})
.catch(function(err){
test.fail(err.message);
})
.finally(done)
.done()
;
});
Promise with fs
module:
var fs = test.promisifyAll(require('fs'));
it('read directory', function(done) {
fs.readdirAsync(directory)
.map(function (filename) {
// called for each file
})
.catch(function(err){
test.fail(err.message);
})
.finally(done)
.done()
;
});
it('read file', function(done) {
fs.readFileAsync(filePath, 'utf8')
.then(function(filename) {
// ...
})
.catch(function(err){
test.fail(err.message);
})
.finally(done)
.done()
;
});
Promise with BDD style:
test.promise
.given(function() {
// ...
})
.when(function() {
// ...
})
.then(function() {
// ...
})
;
See also: promise
Learning
Takes a little time to learn with the tutorials in the guide, the API doc and looking at the many examples of codes in the spec doc and other unit tests.
You are operational and productive from the outset. The style of writing your unit tests is not imposed, it depends on your preferences. Unit.js is flexible enough to fit your coding style without effort on your part.
The mastery of Unit.js is very fast, especially if you already know one of the libraries of assertions (Assert of Node.js, Shoud.js, Must.js, Sinon.js, Atoum).
If you use the Sublime Text editor or the Atom.io editor, I wrote 2 packages of useful snippets for writing unit tests with Unit.js in these code editor.
Community support
- On the IRC channel #unit.js (freenode).
- GitHub