React Native)では、ネットワーク要求を実行するためにfetch
を使用しますが、fetch
は明示的に必要なモジュールではないため、Jestでモックすることは不可能に思えます。
テストでfetch
を使用するメソッドを呼び出そうとしても、結果は次のようになります。
ReferenceError:フェッチが定義されていません
Jestとネイティブに反応して、そのようなAPIリクエストをテストする方法はありますか?
テストケース内で、Jestのモックを使用して、必要な機能をモックできます。
fetch = jest.fn(() => Promise.resolve());
このアプローチは、promiseベースのテストケースでのみ機能します(Jestドキュメントのpit
を参照)。
fetch
が非同期関数である限り、pit
を使用してすべてのテストを実行する必要があります(非同期テストの詳細はこちら here )。
グローバルfetch
オブジェクトをモックする別のアプローチ:
const mockSuccesfulResponse = (
status = 200,
method = RequestType.GET,
returnBody?: object
) => {
global.fetch = jest.fn().mockImplementationOnce(() => {
return new Promise((resolve, reject) => {
resolve({
ok: true,
status,
json: () => {
return returnBody ? returnBody : {};
},
});
});
});
};
上記のヘルパーメソッドは、任意の方法で変更できます。
独自のモックを作成する代わりに、 jest-fetch-mock npmパッケージを使用してグローバルフェッチオブジェクトをオーバーライドできます。このパッケージを使用すると、偽の応答を設定し、送信された要求を確認できます。広範な使用例については、そのリンクを参照してください。
@ArthurDentureが推奨するように、 fetch-mock を使用できますが、React NativeおよびJestで動作させるためにインストールする必要がある追加のパッケージがいくつかあります。
$ npm install --save-dev fetch-mock
$ npm install --save-dev babel-plugin-transform-runtime
$ npm install --save-dev babel-preset-env
その後、テストでフェッチリクエストをモックできます。以下に例を示します。
// __tests__/App.test.js
import React from 'react';
import App from '../App';
import fetchMock from 'fetch-mock';
import renderer from 'react-test-renderer';
it('renders without crashing', () => {
fetchMock.mock('*', 'Hello World!');
const rendered = renderer.create(<App />).toJSON();
expect(rendered).toBeTruthy();
});
isomorphic-fetch
を追加してこれを解決しました。
$ npm install --save isomorphic-fetch
そしてそれを次のように使用します
import fetch from 'isomorphic-fetch';
...
fetch('http://foo.com');
whatwg-fetchも機能する可能性があります
解決と拒否のケースをテストする場合、まずフェッチ動作をモックしてからJestのrejectsおよびresolvesメソッドを使用しますアサーションブロック付き
function fetchTodos() {
return fetch(`${window.location.Origin}/todos.json`)
.then(response => response.json())
.catch(error => console.log(error))
}
describe('fetchTodos', () => {
it('returns promise resolving to parsed response', () => {
global.fetch = jest.fn(() => Promise.resolve({ json: () => ''}))
expect(fetchTodos()).resolves.toBe('');
})
it('returns promise handling the error', async () => {
global.fetch = jest.fn(() => Promise.reject(''))
expect(fetchTodos()).rejects.toBe('')
})
})