Writing tests with Mocha and jsdom

Mocha is a testing framework built in Node. To start using its command line interface, install it globally via $ npm install -g mocha. Then, you can run the example tests in the repo like this:

$ cd /path/to/repo/jsxquery-demo
$ npm test

This runs every test written in the test directory. You can run just those tests in a single file if you want, too:

$ npm test test/main_menu_spec.js

Setting up a DOM within Node using jsdom

If you take a look at that main_menu_spec.js file, you will notice that those two blocks for 'when user is logged in' and 'when user is not logged in' contain before hooks.

It's thanks to these that the global variables $ and window available in your tests. Now, you can use jQuery to interact with the DOM just like you would in the browser!

test/main_menu_spec.js

// ...

describe('Main menu navigation component', () => {
  describe('when user is logged in', () => {
    before((done) =>
      setupDom(<MainMenu {...user.userIsLoggedIn} />, done)
    );

    // ...

  });
});

That setupDom() function uses jsdom to render markup from a component MainMenu. Those props are made up of some pre-written test data.

Now we can write tests for our component without opening up a browser or anything! Jsdom is especially nice because it's lightweight, and much faster than similar tools like Selenium or PhantomJS.

Writing assertions

Tests are made up of assertions. A little library called expect makes the process of writing assertions really simple.

Testing for the presence of an element in the DOM

Since we have our window and jQuery available in our tests now, we can use basic jQuery to test for the presence of an element.

test/main_menu_spec.js

// ...
describe('Main menu navigation component', () => {
  describe('when user is logged in', () => {
    // ...

    it('displays welcome message', () => {
      expect($('#welcome-message').length).toEqual(1)
    });
  });
});

We can run $ npm test and watch this pass because MainMenu contains an element with the id 'welcome-message'.

$ npm test
...
Main menu navigation component
    when user is logged in
      ✓ displays welcome message
...

Testing for the absence of an element in the DOM

However, MainMenuComponent is only supposed to render '#welcome-message' if its prop userIsLoggedIn is true. To test this behavior, we set up a new DOM with MainMenuComponent and different test data.

test/main_menu_spec.js

describe('Main menu navigation component', () => {
  // ...

  describe('when user is not logged in', () => {
    before((done) =>
      setupDom(<MainMenu {...user.userIsNotLoggedIn} />, done)
    );

    // ...

  });
});

In this block, we're using the object userIsNotLoggedIn instead of userIsLoggedIn from our pre-written test data. Now, the prop userIsLoggedIn is set to false, meaning the element should not render. Sure enough, this test passes, too.

$ npm test
...
  Main menu navigation component
    when user is logged in
      ✓ displays welcome message
      ...
    when user is not logged in
      ✓ does not display welcome message
...

More advanced testing

The repo is set up with examples for more complex tests, including tests for jQuery event handlers/DOM manipulation. Notice the code in the tests is just ordinary jQuery! Once you understand the basics of the Mocha/expect APIs, you can use your existing jQuery skills to set up automated tests that can do in seconds what would take you minutes. Take a moment to explore the examples and you'll see what I mean.

results matching ""

    No results matching ""