Vitestでnode-fetchのfetchをmockする
やりたいこと
フロントエンドJavascriptのfetchをVitestでmockしたいという記事を書きました。
これを実現するために、いろいろと調べた過程で、副産物として、Vitestでnode-fetchのfetchをmockする方法を実装したので、まとめておきます。環境の導入
まだ、Vitest[1]はメジャーなツールではないので、一応、導入方法についても書いておきます。
npm i -D vitest vi-fetch node-fetch
テスト対象の関数
記事用に、かなり簡素化したテスト対象の関数を作ります。この関数は、https://hogehoge.hogehoge.hogehoge というサイトをGETして、そのレスポンスのjsonにあるcountの値を返すだけです。
import fetch from "node-fetch";
export const getCountNode = async () => {
const response = await fetch("https://hogehoge.hogehoge.hogehoge"); // GETする
const countJson = await response.json(); // Responseのbodyをjsonで得る
return countJson.count; // 得られたjsonのcountの値を返す
};
テストを書く
テストを書きます。VitestはJestと多くの部分で互換性があります。Jestにはnode-fetchをmockする方法が公式で公開されていて[3]、これを参考に作れば良いのですが、jest.requireActual
ヘルパーはVitestにはありません。そのため、stack overflowでE. Colemanらが示している方法[1:1]を参考に、実装しています。
import { describe, it, expect, vi } from "vitest";
import fetch from "node-fetch";
import { getCountNode } from "./getCountNode";
describe("sample", () => {
it("hello", async () => {
vi.mock("node-fetch");
fetch.mockReturnValue(
Promise.resolve({ json: () => Promise.resolve({ count: 33 }) })
);
const result = await getCountNode();
expect(result).toBe(33);
});
});
テストを実行してみる
実行すると、以下のように通ります。テスト結果が2 passedになっているのはフロントエンドJavascriptのfetchを同時にテスト[2:1] しているからです(手抜きですみません)。
わざと通らないようにする
わざとテストが通らないようにテストコードを変更してみます。
import { describe, it, expect, vi } from "vitest";
import fetch from "node-fetch";
import { getCountNode } from "./getCountNode";
describe("sample", () => {
it("hello", async () => {
vi.mock("node-fetch");
fetch.mockReturnValue(
Promise.resolve({ json: () => Promise.resolve({ count: 33 }) })
);
const result = await getCountNode();
expect(result).toBe(31);
});
});
結果はこちら
さいごに
この記事は、以下の記事のおまけです。フロントエンドJavascriptのfetchをモックしたい人はぜひ、一読ください。
-
asked by BobMorane, answered by E. Coleman / Jest - TypeError: response.json is not a function https://stackoverflow.com/questions/58599735/jest-typeerror-response-json-is-not-a-function (2022-04-17閲覧) ↩︎ ↩︎
-
Akira Kashihara / VitestでフロントエンドJavascriptのfetchをmockする https://zenn.dev/akira_kashihara/articles/650c558ae02db0 (2022-04-17閲覧) ↩︎ ↩︎
-
Jest / モジュールモックのバイパス https://jestjs.io/ja/docs/next/bypassing-module-mocks (2022-04-17閲覧) ↩︎
Discussion