Categories: Uncategorized

Browser Side Unit test by Mocha and Chai – From Prepare Environment to jQuery Deferred

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

  • OS
    • Windows 7 Enterprise SP1
  • Mocha
    • 2.2.5
  • Chai
    • 3.1.0
  • jQuery
    • 2.1.4

Prepare Environment

 Following is directory architecture because I’ll use CDN for Chai, Mocha and jQuery.
.
├── spec
│   ├── main_spec.js
│   └── spec_runner.html
└── src
    └── main.js

2 directories, 3 files

Test Synchronizing Process

 Test target function is following.
function double(n) {
  if(!n) {
    throw new Error("no param");
  } else {
    return n * n;
  }
}
 Following test function.
describe('SampleTest', function(){

  describe('Test Double Func', function(){
    it('should return double value', function(){
      expect(double(2)).to.equal(4); //except assertion
      double(3).should.equal(9); //should assertion
    });

    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.
<html>
<head>
  <meta charset="utf-8">
  <title>Mocha Tests</title>
  <link href="https://cdn.rawgit.com/mochajs/mocha/2.2.5/mocha.css" rel="stylesheet" />
</head>
<body>
  <div id="mocha"></div>

  <script type="text/javascript" src="https://cdn.rawgit.com/mochajs/mocha/2.2.5/mocha.js"></script>
  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/chai/3.1.0/chai.js"></script>

  <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.
function doubleAsync(n, callback) {
  setTimeout(function(){
    callback(n * n);
  }, 100);
}
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.
function api_data() {
  var deferred = jQuery.ajax({
    url: "https://app.rakuten.co.jp/services/api/IchibaItem/Search/20140222?format=json&keyword=%E6%A5%BD%E5%A4%A9&genreId=559887&shopCode=rakuten24&applicationId=#{Please input your id}",
    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”.
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.
<html>
<head>
  <meta charset="utf-8">
  <title>Mocha Tests</title>
  <link href="https://cdn.rawgit.com/mochajs/mocha/2.2.5/mocha.css" rel="stylesheet" />
</head>
<body>
  <div id="mocha"></div>

  <script src="https://cdn.rawgit.com/jquery/jquery/2.1.4/dist/jquery.min.js"></script>
  <script type="text/javascript" src="https://cdn.rawgit.com/mochajs/mocha/2.2.5/mocha.js"></script>
  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/chai/3.1.0/chai.js"></script>

  <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.
zuqqhi2