First, enable Babel support in Jest as documented in the Getting Started guide.
Let's implement a simple module that fetches user data from an API and returns the user name.
우선, Getting Started 가이드에서 설명된 데로 Jest에서 Babel 적용을 활성화 하자.
API로 부터 user 데이터를 패치하고 user name을 반환하는 간단한 모듈을 구현하자.
// user.js
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.
위 구현에서 request.js
모듈로 부터 promise를 반환할 것이다. user name을 받기 위해 then
체인을 호출했다.
Now imagine an implementation of request.js
that goes to the network and fetches some user data:
이제 네트워크로 이동하여 일부 user data를 가져오는request.js
구현을 생각해 보자.
// request.js
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:
테스트에서 네트워크로 이동하는 것을 원하지 않기 때문에, __mocks__
폴더안에 request.js
모듈을 위한 수동mock을 생성 할 것이다. 다음과 같이 보일 수 있다:
// __mocks__/request.js
const users = {
4: {name: 'Mark'},
5: {name: 'Paul'},
};
export default function request(url) {
return new Promise((resolve, reject) => {
const userID = parseInt(url.substr('/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.
이제 비동기 기능에 대한 테스트를 작성해 보자.
// __tests__/user-test.js
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).toEqual('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.
jest.mock('../request')
호출하여 Jest에게 수동 mock을 사용하기하도록 지시한다. it
에 반환 값으로 resolved가 될 Promise가 될 것으로 기대된다. 마지막에 Promise로 리턴이 된다면 언제든 expect
호출하고 원하는 만큰 Promises를 체인걸 수 있다.
.resolves
There is a less verbose way using resolves
to unwrap the value of a fulfilled promise together with any other matcher. If the promise is rejected, the assertion will fail.
matcher와 함게 promise로 가득찬 값을 풀기위해 resolves
를 사용하는 방법은 많지 않다.(??) 만약 promise가 거부된다면, assertion은 실패 할 것이다.
it('works with resolves', () => {
expect.assertions(1);
return expect(user.getUserName(5)).resolves.toEqual('Paul');
});
async
/await
Writing tests using the async
/await
syntax is easy. Here is how you'd write the same examples from before:
async
/await
사용하여 테스트를 작성하는 것은 쉽다. 이전 예제를 작성하는 방법은 다음과 같다:
// async/await can be used.
it('works with async/await', async () => {
expect.assertions(1);
const data = await user.getUserName(4);
expect(data).toEqual('Mark');
});
// async/await can also be used with `.resolves`.
it('works with async/await and resolves', async () => {
expect.assertions(1);
await expect(user.getUserName(5)).resolves.toEqual('Paul');
});
To enable async/await in your project, install babel-preset-env
and enable the feature in your .babelrc
file.
프로젝트에서 async/await를 활성화하기 위해, babel-preset-env
인스톨하고 .babelrc 파일에 기능을 활성화 하자.
Error handling
Errors can be handled using the .catch
method. Make sure to add expect.assertions
to verify that a certain number of assertions are called. Otherwise a fulfilled promise would not fail the test:
.catch
메소드를 사용하여 에러를 핸들링할 수 있다. expect.assertions
를 추가하여 특정 수의 assertion이 호출되는지 확인하자. 그렇지 않으면 성취된 promise가 실패하지 않을 것이다.(???)
// Testing for async errors using Promise.catch.
test('tests error with promises', () => {
expect.assertions(1);
return user.getUserName(2).catch(e =>
expect(e).toEqual({
error: 'User with 2 not found.',
}),
);
});
// Or using async/await.
it('tests error with async/await', async () => {
expect.assertions(1);
try {
await user.getUserName(1);
} catch (e) {
expect(e).toEqual({
error: 'User with 1 not found.',
});
}
});
.rejects
The.rejects
helper works like the .resolves
helper. If the promise is fulfilled, the test will automatically fail.
.rejects
헬퍼는 .resolves
해퍼처럼 작동한다. 만약 promise가 성취한다면, 테스트는 자동적으로 실패할 것이다.
// Testing for async errors using `.rejects`.
it('tests error with rejects', () => {
expect.assertions(1);
return expect(user.getUserName(3)).rejects.toEqual({
error: 'User with 3 not found.',
});
});
// Or using async/await with `.rejects`.
it('tests error with async/await and rejects', async () => {
expect.assertions(1);
await expect(user.getUserName(3)).rejects.toEqual({
error: 'User with 3 not found.',
});
});
The code for this example is available at examples/async.
If you'd like to test timers, like setTimeout
, take a look at the Timer mocks documentation.