It's common in JavaScript for code to run asynchronously. When you have code that runs asynchronously, Jest needs to know when the code it is testing has completed, before it can move on to another test. Jest has several ways to handle this.
Javascript에서 비동기 실행 코드는 일반적이다. 비동기 실행 코드가 있을 때, Jest는 다른 테스트로 넘어가기 전에 언제 테스트 코드가 완료 되는지 알아야 한다. Jest는 이처리를 할 수 있는 몇가지 방법을 가지고 있다.
Callbacks
The most common asynchronous pattern is callbacks.
가장 일반적인 비동기 패턴은 콜백이다.
For example, let's say that you have a fetchData(callback)
function that fetches some data and calls callback(data)
when it is complete. You want to test that this returned data is just the string 'peanut butter'
.
예를들어, 어떤 데이터를 fetch하고 완료가 되면 callback(data)
을 호출하는 fetchData(callback)
함수를 갖고 있다고 해보자. 단지 'peanut butter'
문자열을 리턴하는 테스트를 하려고 합니다.
By default, Jest tests complete once they reach the end of their execution. That means this test will not work as intended:
기본적으로, Jest 테스트는 실행이 끝나면 완료됩니다. 이 테스트는 의도 한대로 작동하지 않는다는 걸 의미합니다:
// Don't do this!
test('the data is peanut butter', () => {
function callback(data) {
expect(data).toBe('peanut butter');
}
fetchData(callback);
});
The problem is that the test will complete as soon as fetchData
completes, before ever calling the callback.
문제는 fetchData
완료 되자마자 테스트는 종료될 것이다, callback이 호출 되기 전에.
There is an alternate form of test
that fixes this. Instead of putting the test in a function with an empty argument, use a single argument called done
. Jest will wait until the done
callback is called before finishing the test.
이 문제를 해결하는 다른 형태의 테스트가 있다. 빈 argument가 있는 테스트 함수 대신 done 호출하는 단일 argumenet를 사용하자. Jest는 테스트가 끝나기 전에 불려지는 done 호출될 때까지 기다릴 것이다.
test('the data is peanut butter', done => {
function callback(data) {
expect(data).toBe('peanut butter');
done();
}
fetchData(callback);
});
If done()
is never called, the test will fail, which is what you want to happen.
만약 done()이 호출되지 않으면 테스트는 실패 합니다.
Promises
If your code uses promises, there is a simpler way to handle asynchronous tests. Just return a promise from your test, and Jest will wait for that promise to resolve. If the promise is rejected, the test will automatically fail.
만약 promises를 사용하면, 비동기 테스트들을 간단히 조작하는 방법이 있다. 단지 테스트에서 promise를 리턴하고, Jest는 promise가 리졸브 될때까지 기다릴 것이다. 만약 promise가 거부되면, 테스트는 자동적으로 실패 될 것이다.
For example, let's say that fetchData
, instead of using a callback, returns a promise that is supposed to resolve to the string 'peanut butter'
. We could test it with:
예를들어,콜백을 사용하는 대신 'peanut butter'
문자열을 리졸브한다고 가정되는 promise를 리턴하는 fetchData
를 사용해 보자. 테스트는 이와같이 될 수 있다:
test('the data is peanut butter', () => {
expect.assertions(1);
return fetchData().then(data => {
expect(data).toBe('peanut butter');
});
});
Be sure to return the promise - if you omit this return
statement, your test will complete before fetchData
completes.
fetchData
완료되기 전에 테스트는 끝날것이다.If you expect a promise to be rejected use 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.
만약 promise가 거부될거라고 예상되면, .catch 메소드를 사용하자. expect.assertions
를 사용하여 특정 수의 어설션이 호출되는지 확인 하자. 그렇지 않으면 (fulfilled)promise는 테스트에 실패할 것이다.
test('the fetch fails with an error', () => {
expect.assertions(1);
return fetchData().catch(e => expect(e).toMatch('error'));
});
.resolves
/ .rejects
You can also use the .resolves
matcher in your expect statement, and Jest will wait for that promise to resolve. If the promise is rejected, the test will automatically fail.
또한 expect 문에서 .resolves
matcher를 사용할 수 있고 Jest는 promise가 리졸브 되기를 기다릴 것이다. 만약 promis가 거부되면, 테스트는 자동적으로 실패 될 것이다.
test('the data is peanut butter', () => {
expect.assertions(1);
return expect(fetchData()).resolves.toBe('peanut butter');
});
Be sure to return the assertion—if you omit this return
statement, your test will complete before fetchData
completes.
assertion을 리턴하자- 만약 이 return
문을 생략하면, 너는 fetchData
완료되기 전에 테스트는 끝날 것이다.
If you expect a promise to be rejected use the .rejects
matcher. It works analogically to the .resolves
matcher. If the promise is fulfilled, the test will automatically fail.
만약 promise가 거부될거라고 예상되면 .rejects
matcher를 사용하자. .resolves
matcher와 유사하게 작동한다. 만약 promise가 성공하면, 테스트는 자동적으로 실패할 것이다.
test('the fetch fails with an error', () => {
expect.assertions(1);
return expect(fetchData()).rejects.toMatch('error');
});
Async/Await
Alternatively, you can use async
and await
in your tests. To write an async test, just use the async
keyword in front of the function passed to test
. For example, the same fetchData
scenario can be tested with:
또는, 테스트에서 async
and await
를 사용할 수 있다. async 테스트를 작성하기 위해, 단지 async
키워드를 test
에 전달된 함수의 앞에 사용하면된다. 예를들어, 동일한 fetchData
시나리오를 다음과 같이 테스트 할 수 있다:
test('the data is peanut butter', async () => {
expect.assertions(1);
const data = await fetchData();
expect(data).toBe('peanut butter');
});
test('the fetch fails with an error', async () => {
expect.assertions(1);
try {
await fetchData();
} catch (e) {
expect(e).toMatch('error');
}
});
Of course, you can combine async
and await
with .resolves
or .rejects
.
물론 async
and await
에 .resolves
or .rejects
를결합 할 수 있다:
test('the data is peanut butter', async () => {
expect.assertions(1);
await expect(fetchData()).resolves.toBe('peanut butter');
});
test('the fetch fails with an error', async () => {
expect.assertions(1);
await expect(fetchData()).rejects.toMatch('error');
});
In these cases, async
and await
are effectively just syntactic sugar for the same logic as the promises example uses.
이 경우, async
and await
는 promised 예제가 사용하는 것과 같은 로직에 대한 달콤한 문법일 뿐이다.
None of these forms is particularly superior to the others, and you can mix and match them across a codebase or even in a single file. It just depends on which style makes your tests simpler.
이 폼들은 다른 것들과 비교하여 특별히 우수하거나 하지 않으므로, 코드베이스 또는 심지어 단일 파일에서 혼합하여 사용할 수 있다. 테스트를 단순하게 만드는 스타일에 따라 달라진다.
※ 역자 추가 작업
1. assertion call count: 말그대로 테스트 확인이(expect.toBe expect.Equal등.. ) 몇번 일어나냐?