Jest実行時の fetch is not defined エラーに対処する - のこのこかずのこ

のこのこかずのこ

10年エンジニアやってるけどいまだになんもわからん

Jest実行時の fetch is not defined エラーに対処する

問題のコード

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することで解決した。

www.npmjs.com

参考にさせていただきました : 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を使うってことで問題ないけど、これは罠だな〜…