React 入門 (14) ~ TODOアプリを作る(9) ~ sendToApiServer のテスト
今日は sendToApiServer のテスト。fetch が絡むので mock ライブラリを導入する。
$ npm i --save fetch-mock $ npm i --save @types/fetch-mock
fetchMock は import * as fetchMock from 'fetch-mock'
でインポート可能。
一旦以下のように作ってnpm test
を実行してみる。
import sendToApiServer from './sendToApiServer' describe('sendToApiServer', () => { it('ADD_TODO', () => { const action = { type: 'ADD_TODO', text: "test", } sendToApiServer({}, action) }) })
すると、以下のようなエラーが表示された。
FAIL src/utils/sendToApiServer.test.tsx ● Test suite failed to run TypeScript diagnostics (customize using `[jest-config].globals.ts-jest.diagnostics` option): src/utils/sendToApiServer.test.tsx:9:21 - error TS2345: Argument of type '{}' is not assignable to parameter of type 'Dispatch<any>'. Type '{}' provides no match for the signature '<T extends any>(action: T): T'. 9 sendToApiServer({}, action) ~~
どうも型が一致していないようだ。ここはいったん sendToApiServer.tsx
側の型を any
にして無理やり通すことにした。
続いて、fetchMock を足してテストを通す。
import * as fetchMock from 'fetch-mock' import sendToApiServer from './sendToApiServer' describe('sendToApiServer', () => { it('ADD_TODO', async () => { const action = { type: 'ADD_TODO', text: "test", } fetchMock.post('/api/add_todo', {body: {'type':'ADD_TODO', 'text':'test'}, status: 200}); const mockDispatch = jest.fn() await sendToApiServer(mockDispatch, action) expect(mockDispatch.mock.calls.length).toBe(1) expect(mockDispatch.mock.calls[0][0]).toEqual(action) }) })
sendToApiServer() 自体は非同期で動作するので、await
をつける。つけないと mockDispatch
が呼ばれる前にexpect() の評価がされてしまう。あと、await
をつけるなら テスト関数自体を async
にしないと怒られるのでつけておくこと。
fetchMock は post 関数を呼ぶことで post がきたときのみ動作するようになる。body には返り値を指定する。
私の設計では、渡したアクションをそのまま返すので、はじめはactionのオブジェクトをbodyに設定していたが、元のアクションが間違っていた場合にテストが通ってしまうな。と思ったので、めんどくさいが分けて書くことにした。
COMPLETE_TODO
、DELETE_TODO
に関しても同様にテストを記載した。ADD_TODO
と変わるところはないので、省略
FETCH_TODO
もテストを追加する。FETCH_TODO
は返り値がDBの状況によって変化するため、いくつかテストパターンを書いたほうがいいと思い、describe
でネストしてその下にテストを追加した。そうした場合に fetchMock がエラーを出力するようになった。原因はテストケースをまたいでfetchMock が使用されてしまい、関数が再定義されてしまうためのようだ。各テストケースの終わりに fetchMock.restore()
で解放してやることで問題なく動作するようになった。
成果物は以下。
GitHub - bamchoh/react-study at c711a96976f8f9df82f0b17bacd334535c339cb0
次回は サーバーサイドのテストを書く予定。