Do browser side unit test using
Mocha and
Chai.
This article includes how to prepare environment, how to test synchronizing process, how to test asynchronizing process and how to test jQuery Deferred.
Environment
Prepare Environment
Following is directory architecture because I’ll use CDN for Chai, Mocha and jQuery.
Directory Architecture1 2 3 4 5 6 7 8 | .
├── spec
│   ├── main_spec.js
│   └── spec_runner.html
└── src
└── main.js
2 directories, 3 files
|
Test Synchronizing Process
Test target function is following.
main.js1 2 3 4 5 6 7 | function double(n) {
if (!n) {
throw new Error( "no param" );
} else {
return n * n;
}
}
|
Following test function.
main_spec.js1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | describe( 'SampleTest' , function (){
describe( 'Test Double Func' , function (){
it( 'should return double value' , function (){
expect(double(2)).to.equal(4);
double(3).should.equal(9);
});
it( 'should throw error undefined without param' , function (){
expect( function () { double() }).to. throw ( "no param" );
});
});
});
|
When we do browser side unit test, we need to prepare spec_runner.html which includes loading javascripts and settings for mocha and chai.
spec_runner.js1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <html>
<head>
<meta charset="utf-8">
<title>Mocha Tests</title>
</head>
<body>
<div id="mocha"></div>
<script>
mocha.setup('bdd')
var assert = chai.assert;
var expect = chai.expect;
chai.Should();
</script>
<script src="../src/main.js"></script>
<script src="./main_spec.js"></script>
<script>
mocha.checkLeaks();
mocha.run();
</script>
</body>
</html>
|
When you want to run test, just double-click spec_runner.html.
Following screen means the test target code passed all test cases.
Test Asynchronizing Process
When you want to test code including callback, you should like following.
main2.js1 2 3 4 5 | function doubleAsync(n, callback) {
setTimeout( function (){
callback(n * n);
}, 100);
}
|
main_spec2.js1 2 3 4 5 6 7 8 | describe( 'Test DoubleAsync Func' , function (){
it( 'should return double value' , function (done){
doubleAsync(2, function (result){
result.should.equal(4);
done();
});
});
});
|
”done” is important part. When you forget to write “done” in test code, the testing never stop.
Following image is result of test for asynchronizing process.
jQuery Deferred
Basically same as asynchronizing process test.
main3.js1 2 3 4 5 6 7 8 9 10 | function api_data() {
var deferred = jQuery.ajax({
dataType: "jsonp"
})
.done( function (items) {})
.fail( function (error) {})
return deferred;
}
|
This code access
Rakuten Item Search API, then get the result. When you want to test upper code, you should use “always”.
main3.js1 2 3 4 5 6 7 8 9 10 11 12 13 14 | describe( 'SampleTest' , function (){
describe( 'API Data Func' , function (){
it( 'should return correct dada' , function (done){
api_data().always( function (result) {
expect(result[ 'page' ]).to.equal(1);
done();
});
});
});
});
|
Important part is spec_runner.html.
spec_runner3.html1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | <html>
<head>
<meta charset="utf-8">
<title>Mocha Tests</title>
</head>
<body>
<div id="mocha"></div>
<script>
mocha.setup('bdd')
var assert = chai.assert;
var expect = chai.expect;
chai.Should();
</script>
<script src="../src/main3.js"></script>
<script src="./main_spec3.js"></script>
<script>
mocha.checkLeaks();
mocha.globals(['jQuery*']);
mocha.run();
</script>
</body>
</html>
|
If you forget to write mocha.globals. You’ll see following error.
We need to specify global variable names for Mocha.
The test target code includes global variables “jQuery” and “jQuery[0-9]+”(which is used by jQuery Ajax JSONP).
Second one’s variable name will be changed. So we need to use wildcard like “jQuery*”.
Right result is following.