問題のコード
Jestでテストしたかったのは、TypeScriptでfetch()を使った簡単な関数。
export function getData(): Promise<Profile> { return fetch("https://jsonplaceholder.typicode.com/users").then(handleResponse); }
事象に直接は関係ないけど、テストコードはこんな感じ。
test("データ取得成功", async () => { await expect(getData()).resolves.toHaveLength(10); });
npm test
でテスト実行すると、 ReferenceError: fetch is not defined
エラーとなった。
関数の方をts-nodeで実行すれば、エラーにはならずにfetchは問題なく実行される。どうやらJestを通すとfetchが見つからなくなってしまうようだ。
解決方法
結論から言うと、 cross-fetch
をimportすることで解決した。
参考にさせていただきました : Jest × React Testing Library × msw で fetch を使ってるコンポーネントのテストでエラーになった - かもメモ
npmでインストール。
npm i -D cross-fetch
テストファイルにimportする。
この時に、cross-fetch/polyfill
をimportすることで、グローバルにインポートできるみたい。なので、実際にfetch()を実行するファイルでなくても、テストファイルでimportすればOK。もしくは、すべてのテストに適用されるように jest.setup.ts でimportしといてもいいかも。
import 'cross-fetch/polyfill';
でもなんで?
Node.jsはv20.11.1、Jestは v29.4 を使っているので、fetchがデフォルトで使えてもいいと思うのだが…。 と思って調べたら、こちらの記事が大変参考になりました。
node v18 で導入された global fetch を jsdom 環境下の jest で利用する方法 #Node.js - Qiita
jest.config.ts を確認したら、まさに jest-environment-jsdom
を使っていたので、こいつが悪さをしてるみたい。
とりあえず今回は、polyfillを使うってことで問題ないけど、これは罠だな〜…