Beautiful Assertions with Chai

So far, we’ve looked at using Mocha for doing unit testing. While using Mocha’s native assertions works fine, they can look a bit opaque the first time they are being viewed. Even with experience, seeing something like this takes some time to decipher:

assert.equal(2, addingMachine(1, 1));

While we look at this code, we might say something like this to ourselves:

Okay, so we’re saying that the things that will come up next will be equal. Okay, 2 should be equal to the result of putting one and one into the addingMachine.

That’s not so bad. But there’s a way to make our tests even easier to read. Suppose we could do this instead:

expect(2).to.equal(addingMachine(1, 1));

Now, our internal dialogue is so straight forward that I’m afraid you might be insulted that I wrote it out:

Okay, we expect 2 to equal the results of putting one and one into the addingMachine

If such gains can be made for a relatively simple assertion, think of the mental load that we save with more complex statements.

How can we do this? With a neat assertion library called Chai. Let’s talk about how to get it set up with Node:

Chai with Node: expect

  1. (If you haven’t already) Run npm init to set up your project.
  2. Run npm install mocha --save-dev to get Mocha installed. You can also use a different test runner if you prefer.
  3. Run npm install chai --save-dev to get Chai.

Now that you’re set up, let’s get the test file set up. At the top of your file, require expect like this: const expect = require('chai').expect; You can also just require Chai, and this means that you don’t need a separate require if you want to use Chai’s should. I like find that the readability gained by using the first option makes up for the inconvenience of having to require multiple things, but use what’s most readable for you.

If we’re using the same example of the addingMachine, we can now use expect to write some tests:

describe ('addingMachine', function () {
  it ('should handle negative numbers properly, returning 5 as the sum of 10 and -5', function () {
    expect(5).to.equal(addingMachine(10, -5));
  });
});

We can also use it to test error handling:

describe ('addingMachine Error Handling', function () {
  it ('should throw if passed a non-number (NaN)', function () {
    expect(addingMachine.bind(null, NaN, 5)).to.throw('passed NaN');
  });
});

Chai with Node: should

Another part of the Chai API is should. I like to use should with error handling. It reads better:

const should = require('chai').should(); // note `should` is being invoked
//snip
describe ('addingMachine Error Handling', function () {
  it ('should throw if passed a non-number (NaN)', function () {
    addingMachine.bind(null, NaN, 5).should.throw('passed NaN');
  });
});

Using Chai and Mocha in Node is great. Your tests are more readable and the setup cost of using it is low. Chai can also be run directly in the browser. For more about Chai, check out the website at http://chaijs.com. Let me know if you have any questions.

Leave a Reply

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