zuqqhi2のIT日記

プログラミング + アカデミック + 何か面白いこと

   Jul 20

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

by zuqqhi2 at 2015年7月20日
Pocket

 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.

main_spec1

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.

main_spec2

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.

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

main_spec3

Related Posts

Pocket

You can follow any responses to this entry through the RSS 2.0 feed. Both comments and pings are currently closed.