An Async Example
First, enable Babel support in Jest as documented in the Getting Started guide.
Let's implement a module that fetches user data from an API and returns the user name.
import request from './request';
export function getUserName(userID) {
return request(`/users/${userID}`).then(user => user.name);
}
In the above implementation, we expect the request.js
module to return a promise. We chain a call to then
to receive the user name.
Now imagine an implementation of request.js
that goes to the network and fetches some user data:
const http = require('http');
export default function request(url) {
return new Promise(resolve => {
// This is an example of an http request, for example to fetch
// user data from an API.
// This module is being mocked in __mocks__/request.js
http.get({path: url}, response => {
let data = '';
response.on('data', _data => (data += _data));
response.on('end', () => resolve(data));
});
});
}
Because we don't want to go to the network in our test, we are going to create a manual mock for our request.js
module in the __mocks__
folder (the folder is case-sensitive, __MOCKS__
will not work). It could look something like this:
const users = {
4: {name: 'Mark'},
5: {name: 'Paul'},
};
export default function request(url) {
return new Promise((resolve, reject) => {
const userID = parseInt(url.slice('/users/'.length), 10);
process.nextTick(() =>
users[userID]
? resolve(users[userID])
: reject({
error: `User with ${userID} not found.`,
}),
);
});
}
Now let's write a test for our async functionality.
jest.mock('../request');
import * as user from '../user';
// The assertion for a promise must be returned.
it('works with promises', () => {
expect.assertions(1);
return user.getUserName(4).then(data => expect(data).toBe('Mark'));
});
We call jest.mock('../request')
to tell Jest to use our manual mock. it
expects the return value to be a Promise that is going to be resolved. You can chain as many Promises as you like and call expect
at any time, as long as you return a Promise at the end.