Testing JavaScript Code with Jest

Orinami Olatunji
Jul 24, 2017 · 6 min read

Jest offers a complete and easy to set-up JavaScript testing solution and work out of the box for any React project. Isn’t that awesome?

Why Jest?

Jest is used by Facebook to test all JavaScript code including React applications. One of Jest’s philosophies is to provide an integrated “zero-configuration” experience. Jest is currently being used by Facebook, Instagram, Twitter, PayPal, IBM and many more. At this time, Jest currently has over 11,000 stars on GitHub.

Features:
* Jest parallelizes test runs across workers to maximize performance.
* Jest easily creates code coverage reports using — coverage with no extra setup or libraries needed.
* Provides a powerful mocking library for functions and modules.
* Works with TypeScript and integrates seamlessly with babel.

Getting Started

Jest can be used to test any JavaScript application. For React developers, Jest is already configured when you use create-react-app or react-native init to create your React and React Native projects. To enable Jest locate your test file(s) in any JavaScript application, save your test file(s) with the a .spec.js or .test.js extension or place your tests files in a __tests__ folder.

Installation

First, create a folder and then we would create a package.json file using:

cd folder-name
npm init

The installation should look like this:

You have created a package.json file that would keep record of the project information and also dependencies.

Let’s install the jest dependency. For NPM:

npm install — save-dev jest

For Yarn:

yarn add — dev jest

Check that your package.json looks like this:

{
“name”: “jest-tutorial”,
“version”: “1.0.0”,
“description”: “A Jest Tutorial”,
“main”: “index.js”,
“scripts”: {
“test”: “jest”
},
“repository”: {
“type”: “git”,
“url”: “git+https://github.com/codediger/jest-tutorial.git"
},
“keywords”: [
“jest”,
“javascript”
],
“author”: “Orinami Olatunji”,
“license”: “ISC”,
“bugs”: {
“url”: “https://github.com/codediger/jest-tutorial/issues"
},
“homepage”: “https://github.com/codediger/jest-tutorial#readme",
“devDependencies”: {
“jest”: “²⁰.0.4”
}
}

Quick Example

Let’s have a quick example. Create a new file and name it concat.js. Add this code:

//concat.js
function concat(x, y) {
return x + y;
}
module.exports = concat;

Then, create a file named concat.test.js. This is where we would put our test code:

//concat.test.js
const concat = require(‘./concat’);

Run the test using npm test. Here is what you’ll see:

You have just written your first test. Yay!

Introduction to Jest expect API

expect gives you access to a number of matchers that let you validate different things. When writing a test, we want to make sure that the result is as expected. Jest expect API contains a lot of methods you can use in your application. We can’t explore all, but we would look into at expect.assertions() and .toBe().

expect.assertions()

This is very useful when testing asynchronous code to ensure that an assertions in a callback was called. expect.assertions() is used to verify if the number of callback returned is the expected number. This is a sample test that uses expect.assertions() to ensure that all callbacks are called before knowing if the test passed or failed.

test(‘asyncCode calls fetchPicture, fetchName and githubName’, () => {
expect.assertions(3);
function fetchPicture(data) {
expect(data).toBeTruthy();
}
function fetchName(data) {
expect(data).toBeTruthy();
}
function githubName(data) {
expect(data).toBeTruthy();
}
asyncCode(fetchPicture, fetchName, githubName );
});

The expect.assertions(3) makes sure that the 3 callbacks are called before passing or falling the test.

.toBe()

.toBe() basically just checks that value is what you expect it to be. We’ve used this in our quick example. Here’s another one:

// profile.test.js
const profile = {
name: ‘Orinami’,
githubUrl: ‘github.com/orinami’,
twitterUrl: ‘twitter.com/orinami_’
};

The profile.test.js passes because profile is an object and we expect the result of the test to be an object.

More Matchers

I know I said that we would only be exploring two methods, but let’s take a look at a some more in action. Matchers enable us test values in various ways. I’ll list some here:

1. toEqual recursively checks every field of an object or array.
2. toBeNull matches only null
3. toBeUndefined matches only undefined
4. toBeDefined is the opposite of `toBeUndefined`
5. toMatch checks strings against regular expressions.
6. toContain checks if an array contains a particular item.

Let’s see them action. Create a file and save it as matchers.test.js. Add this code and run using npm test:

//toEqual
const data = {
name: ‘Orinami’,
lastname: ‘Olatunji’
};

Here’s the outcome:

We can see that all our test passed successfully. You can manipulate values and see the outcome. There is no better way to learn than to actively try it out!

Testing Asynchronous Code

Handling asynchronous code can be difficult; Testing it? More difficult. Let’s look at how Jest is used to test asynchronous code.

Callbacks

Using callbacks is a popular method for handling asynchronous code in JavaScript. Let’s take a look at this example:

test(‘data: go JavaScript!’, done => {
function callback(value) {
expect(value).toBe(‘go Javascript!’);
done();
}
getMessage(callback);
});

We pass done as an argument so that Jest will wait until the done callback is called before finishing the test. Should you omit done() from the code, the test will not work as it should because the callback function won’t be called at all.

Promises

If your code makes use of promises, just return a promise in your test and Jest would handle the asynchronous call and wait for it to resolve. If the promise is resolved, the test will pass; if not, the test will fail.
Let’s say thatgetMessage, returns a promise with the string ”Learn Web Development on Scotch.io”, We can test it simply with this:

test(‘Learn Web Development on Scotch.io’, () => {
expect.assertions(1);
return getMessage().then(data => {
expect(data).toBe(‘Learn Web Development on Scotch.io’);
});
});

If you don’t use the return keyword, your test will end before it even does anything meaningful.

Jest also has other ways of testing asynchronous code. It offers async, await, .resolves and .rejects usage in writing tests for asynchronous code. For more on testing asynchronous code, check [here](https://facebook.github.io/jest/docs/asynchronous.html).

Built-in Code Coverage Report

Jest can collect code coverage information from the project/directory you’re working in including untested files. To view built-in code coverage report, Install Jest globally. Run:

npm install -g jest

Then:

jest — coverage

Here’s the result:

Conclusion

Jest makes it easy and efficient to write tests for JavaScript Applications. In this tutorial, You’ve learnt how to write and run tests for snippets of JavaScript code. In a later tutorial, I would breakdown testing asynchronous code using Jest into pieces you can easily understand incase you didn’t get the idea here. If you have any question, feel free to ask. I would be glad to hear it!

piecesofcode

Articles on web development. All articles written by Orinami Olatunji, UI Engineer. Website: orinami.space

Orinami Olatunji

Written by

Thinking…

piecesofcode

Articles on web development. All articles written by Orinami Olatunji, UI Engineer. Website: orinami.space

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade