jestで非同期関数をテストする - Qiita
jest で React component をテストする - Qiita
jest で Redux をテストする - Qiita
jestで非同期関数をテストする方法を、以下のドキュメントに沿って、確認します。
Testing Asynchronous Code
PromiseとAsync/Awaitを扱います。コールバックはあまり脳内に残したくないので省略します。
1.テスト環境構築
以下のコマンドでテストディレクトリを作成します。
mkdir async_test
cd async_test
yarn init -y
yarn add jest axios
package.jsonに"scripts"を追加します。
{
"name": "async_test",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"dependencies": {
"axios": "^0.19.0",
"jest": "^24.8.0"
},
"scripts": {
"test": "jest"
}
これでテストは以下のコマンドで実行されるようになります。jestは自動的にxxxx.test.jsという名前のファイルを見つけてテストします。
yarn test
2.Promise
promiseを利用するコードでは、非同期処理のテストを簡単に扱える方法があります。 **テストからpromiseを返すとJestはpromiseが解決されるまで待機します。**逆に読めばpromiseをreturnしなければJestはpromiseが解決されるまで待機しないということでしょう。実験します。
Rest APIのテストにはJSONPlaceholderを利用します。以下のようなJsonが取得できます。
http://jsonplaceholder.typicode.com/posts
const axios = require('axios')
function fetchData(n) {
return axios.get('https://jsonplaceholder.typicode.com/posts/'+n)
}
test('the res.data.id id is 3', () => {
expect.assertions(1) // (1)
return fetchData(3).then(res => { // (2)
expect(res.data.id).toBe(3)
})
})
もしこの(2)の return 文を省略した場合、あなたのテストは、fetchDataがresolveされpromiseが返ってくる前に実行され、then() 内のコールバックが実行される前に完了してしまいます。
returnを削って実行すると以下のようなエラーを吐きます。(2)のthen内のコールバックが呼ばれなかったので、アサーションテスト回数が0となり、(1)のテストに失敗したからです。(1)のテストはアサーションテスト回数が1であることを要求しています。
$ yarn test
yarn run v1.16.0
$ jest
FAIL ./fetch.test.js
? the res.data.id id is 3 (46ms)
● the res.data.id id is 3
expect.assertions(1)
Expected one assertion to be called but received zero assertion calls.
6 |
7 | test('the res.data.id id is 3', () => {
> 8 | expect.assertions(1)
| ^
9 | // return fetchData(3).then(res => {
10 | fetchData(3).then(res => {
11 | expect(res.data.id).toBe(3)
at Object.assertions (fetch.test.js:8:10)
Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 total
Snapshots: 0 total
Time: 2.547s
Ran all test suites.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
3.Async/Await
上のコードをAsync/Awaitで書き直すと以下のようになります。これが一番わかりやすいですね。
const axios = require('axios')
function fetchData(n) {
return axios.get('https://jsonplaceholder.typicode.com/posts/'+n)
}
test('the res.data.id id is 3', async () => {
expect.assertions(1)
const res = await fetchData(3)
expect(res.data.id).toBe(3)
})
今回は以上です。