< Previous: Time for Ajax: Using Jest with Asynchronous Tests   Next: Cleaning up Our Tests: Last Tweaks >

Mocking Ajax with Jest: Making an Asynchronous Test Become Synchronous

In the fourth test we just wrote, we used waitFor() and runs() to have Jest wait for our Ajax code to complete before checking our expectations. This approach works, but it has a problem: unit tests are best when they test only one thing. If there's a bug here, was it because our network code was broken, or because our rendering code was broken?

What we want to do is write a test that can load some JSON from GitHub, inject it into our Detail component, then make sure our code did the right thing. However, we want to do all that without using Ajax, because that introduces a slow network and complicates our test.

Fortunately, there is a marvellously simple solution: GitHub already gives us JSON from its API, which stands for JavaScript Object Notation. If we download some GitHub data to a file, we can load it into a test and immediately use it in place of our Ajax call. With this method, our test runs faster because there's no network delay, we can be sure of always getting good data, and – bonus! – it won't get rate limited by the GitHub API.

I hope you're ready for how easy this is going to be, because we can just use the require() function to load another JavaScript file and use it immediately. As JSON already is JavaScript ready to use, we can just import its contents into our test and start using it.

Add this fifth test now, but don't run it just yet:

__tests__/Detail-test.js

it('fetches forks from a local source', () => {
    const rendered = TestUtils.renderIntoDocument(
        <Detail params={{repo: ''}} />
    );

    const testData = require('./forks.json');
    rendered.setState({mode: 'forks', forks: testData});

    expect(rendered.state.forks.length).toEqual(30);
});

As you can see, we load a JSON file called forks.json (see below) into the constant testData, then use the setState() method of our component to force it to load. Finally, we can expect() that the rendered.state.forks property be set to 30 – easy!

One minor hiccup: we don't actually have the file forks.json yet, but that's easily fixed with a simple terminal command:

curl https://api.github.com/repos/facebook/react/forks > __tests__/forks.json

Make sure you run that from the same place you were running npm run test, and it will download the GitHub forks feed for React to the file tests/forks.json.

Save your changes then run the full suite of tests now – you should see passes all the way down.

If everything is working correctly all six of your tests should pass.

Buy the book for $10

Get the complete, unabridged Hacking with React e-book and take your learning to the next level - includes a 45-day no questions asked money back guarantee!

If this was helpful, please take a moment to tell others about Hacking with React by tweeting about it!

< Previous: Time for Ajax: Using Jest with Asynchronous Tests   Next: Cleaning up Our Tests: Last Tweaks >

Copyright ©2016 Paul Hudson. Follow me: @twostraws.