Attempting to use Mocha & Chai to unit test ES6.

In this post I will cover using Mocha (JS test framework) and Chai (For BDD syntax) to unit test ES6 Javascript in VS Code.

I started working on a small side project, for no reason other than to play with ES6+. It’s a(nother) relatively simple toast library written in as much vanilla JS as possible to avoid reliance on libraries & packages.

I got the code working, but I couldn’t prove that the functions worked. I used qUnit in the past to test JavaScript but if I am completely honest my JavaScript testing knowledge is a bit lacking.

My aim is to get some unit tests for one of my main classes where I can test directly against ES6 and not against the compiled ES5 code. I want the tests to be clear to what they are doing. What I am doing is not new at all, nor is the library! I just wanted to keep notes of how I achieved this first time around.

Disclaimer: This is by no means a comprehensive guide or walkthrough, just the results of me messing about to see if I can get the outcome I wanted whilst learning something new!

Enter, Mocha

I decided to useMocha to do my unit testing, which was chosen purely as it seemed to work well with ES6 code (using Babel). Later I will go into how I also used Chai along side to provide much nicer, fluid assertions using BDD-style syntax.

First of all, I had to install Mocha.

> npm install --save-dev mocha

Then under a new root folder of “test” I created a bread.spec.js – where “bread” here is the name of the class I am testing.

At this point it is fairly easy to create a simple test, like so.

import {Bread} from "../src/bread";
var assert = require('assert');
describe('Fluent methods', function() {
  describe('Title set is not called', function() {
    it('should set the title correctly (null)', function() {
        let options = [ ... code to get options ... ]     
        let b = new Bread(0,"Foo", options);       
      assert.equal(b.Title, null);

I then added the appropriate script to package.json to allow us to run the tests.

 "test": "mocha --require @babel/polyfill --require @babel/register './test/**/*.spec.js'"

Which is ran with:

npm run-script test
VS code window with output of script above. Shows a single completed unit test.
Output of running above command.

This script states that it will run Mocha, on all files under the test directory where the JS file ends with “.spec.js”. I then had to add the 2 requires which enable Mocha to call the ES6 directly and not have to use the transpiled version. Failing to do provide these requires will mean Mocha will not run as it cannot parse ES6.

Using Chai for BDD syntax

In the above, I import my class then create a “test set”. In this test set I then have a single test which is checking if the title gets automatically set. It’s fairly easy to attain what the test does, but it could be clearer. This is where I decided to use Chai. Chai will allow me to have a BDD-style test written which is closer to plain english. Mocha does support some of this (at time of writing) but Chai is much closer to BDD-style syntax I was used to.

To use Chai I need to install the package:

npm install --save-dev chai

Then import the “expect” module from the framework, and refactor the method so it looks a little like this:

import { expect } from "chai";
import {Bread} from "../src/bread";
describe("Fluent methods", () => {
    describe("Title set is not called", () => {
        it("should set the title correctly (null).", () => {
            var options = getValidOptions();            
            let b = new Bread(0,"Foo", options);

Running the tests will yield the same result as before, but now its a lot more readable (In my opinion!)

Not a lot more to add really. Mocha and Chai both have great documentation to read through. The only difficulty I had was getting Mocha to run ES6 directly, as a lot of the information online for this was out of date (that I found…)

Update: I have also posted about debugging using ES6 Mocha tests here

Leave a Reply

Your email address will not be published. Required fields are marked *