Adding Chai/Mocha Tests to your project

Projected Time

45 minutes

Prerequisites

Here are links to lessons that should be completed before this lesson:

Motivation

Learn to use another testing tool for flexibility.

Objectives

Participants will be able to:

Specific Things to Learn

Materials

Lesson

Mocha vs. Jasmine

Both Mocha and Jasmine are popular JavaScript testing frameworks for writing BDD (Behavior-Driven Development) tests. So, why might you choose one over the other?

Jasmine: Jasmine attempts to provide everything that a developer would need in a testing framework. It does not need the browser, the DOM, or any JavaScript framework to work, so it’s simple to get up and running.

Mocha: Mocha does not claim to be a complete testing framework. It is intended to be extended with other frameworks, such as Chai. People like it for its flexibility. It runs on Node and in the browser.

//mocha
expect('bunny').to.not.equal('rabbit');

//jasmine
expect('bunny').not.toEqual('rabbit');

At the end of the day, both Jasmine and Mocha are popular testing frameworks that many companies use. There is no wrong answer: the testing framework that you choose for projects is up to you.

Mocha Test

Let’s get started by setting up a new project with Mocha.

Create a new project

Install Mocha

Create Test Files

Start Test

> mocha



  0 passing (1ms)

Syntax

const assert = require('assert');

describe('Mocha String Test', function() {
  it('should return the exact number of characters in a string', function() {
    assert.equal('Hello'.length, 4); // this line will fail
  });

  it('should return first character of the string', function() {
    assert.equal('Hello'.charAt(0), 'H'); // this line will pass
  });
});
Mocha String Test
  1) should return the exact number of characters in a string
  ✓ should return first character of the string


1 passing (8ms)
1 failing

1) Mocha String Test
     should return the exact number of characters in a string:

    AssertionError [ERR_ASSERTION]: 5 == 4
    + expected - actual

    -5
    +4

    at Context.<anonymous> (test/myTest.js:5:16)
var assert = require('assert');

function asyncFunction(stringToTest, callback) {
  setTimeout(function() {
    callback(stringToTest.charAt(0) === 'H');
  }, 1);
}

// Note: setTimeout has been used to simulate the async behavior
// Warn: Using setTimeout is not the best practice since it's execution time is unpredictable or unreliable

describe('Mocha String Test', function() {
  it('should return first character of the string', function(done) {
    asyncFunction('Hello', function(isValid) {
      assert.equal(isValid, true);
      done();
    });
  });
});

To learn more about testing asynchronous code with Mocha, see the docs.

Chai Test

Let’s install Chai, an assertion library commonly used with Mocha!

install Chai

setting up Chai

const assert = require('chai').assert;

const foo = 'foo';

// Passing
assert.typeOf(foo, 'string');

// Failing - note that the third argument is an optional error message
assert.equal(foo, 'bar', 'foo equal `bar`');
const expect = require('chai').expect;

const foo = 'foo';

// Passing
expect(foo).to.be.a('string');

// Failing
expect(foo).to.equal('bar');
const should = require('chai').should();

const foo = 'foo';

// Passing
foo.should.be.a('string');

// Failing
foo.should.equal('bar');

Note: If you like this style, you can use the should library with Mocha, as that is a common reason to use it over Jasmine.

Common Mistakes / Misconceptions

  1. Not all testing libraries are created the same. These libraries have different and overlapping functionality.

Guided Practice

FizzBuzz (again!) Within your Mocha project, re-write the FizzBuzz test from the Jasmine Testing exercises, using assert syntax. Refer to the docs as needed to find the matchers you need. Ensure that the test passes.

Check your work

const fizzBuzz = require('../src/fizzBuzz');
const assert = require('chai').assert;

describe("fizzBuzz", function() {
it("should be defined", function() {
assert.exists(fizzBuzz);
});

it("should return 'fizz' when given a multiple of 3", function() {
assert(fizzBuzz(3), "fizz");
assert(fizzBuzz(6), "fizz");
});

it("should return 'buzz' when given a multiple of 5", function() {
assert(fizzBuzz(5), "buzz");
assert(fizzBuzz(10), "buzz");
});

it("should return 'fizzbuzz' when given a multiple of 3 and 5", function() {
assert(fizzBuzz(15), "fizzbuzz");
assert(fizzBuzz(30), "fizzbuzz");
});
});

Independent Practice

  1. Re-implement Challenge 1, “Convert Inches to Meters” from Basic JS Practice in a TDD Style. Use Chai’s expect style assertions, referring to the docs as needed. Add assertions that:
input value
metersToInches(0) 0
metersToInches(1) 39.3701
metersToInches(1.5) 59.05515
metersToInches(15.6) 614.17356
  1. We’re going to define a JavaScript object, TDD style! Use any Chai assertion style. After each new test, make the test pass.

Challenge

Do the Mocha and Chai projects have their own internal tests? Read them and see how they are used.

Supplemental Materials

Check for Understanding

Question: What are Mocha and Chai, and how do they work in your project? How do they differ from Jasmine?

Exercise: Every student should pick a Chai assertion, like .to.have.lengthOf. Describe that matcher to the class and how it should be used.