1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JestにおけるError fetching todos: { message: 'ReferenceError: fetch is not defined', details: 'ReferenceError: fetch is not defined}

Posted at

1 はじめに

supabaseと連携したReactアプリにおいて、
Jestとreact-testing-libraryを用いた自動テストで躓いたことが複数個あったため、
それぞれ別記事としてまとめていく
今回は第1弾、ReferenceError: fetch is not definedについて

2 事象

今回、supabaseと連携したReactアプリとして
学習記録アプリを開発した。このアプリは画面を立ち上げた際、
supabaseに登録しているレコードを全件取得したのち、
一覧を表示するといったものである。

image.png

タイトル「学習記録一覧」が
表示されるかを確認しようとし、下記のようなプログラムを作成したところ

Error fetching todos: { message: 'ReferenceError: fetch is not defined', details: 'ReferenceError: fetch is not defined }

が発生
この原因について調査した

TitleTest.spec.jsx
import { LearningRecord } from "../LearningRecord";
import React from "react";
import "@testing-library/jest-dom"
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";

describe("Title Test", () => {
    it("タイトルが学習記録一覧であること", async () => {
        render(<LearningRecord />);

        const title = screen.findByTestId("title");
        expect(title).toHaveTextContent("学習記録一覧");
    });
});

3 原因と解決法

調査したところ、Supabase JSが内部で使用しているfetchを
Jestのテスト実行環境には存在しないからである模様

よって、supabaseを利用したアプリをテストする際は対策を考える方法がある。
そこで今回採用した手法はsupabase関係のプログラムをmockした。

ここでmockとは一言で言うと本物の代わりに使う「ニセモノ」
今回のようなテスト対象外のロジック部分(特に外部依存)を考慮せずに、
テスト対象の箇所だけに着目できるようにするための手法である。

mockを用いて以下のようにプログラムを修正したところ動いた。
TestIdを探すためにはsupabaseから全件取得→描写という動作を待つ必要がある為、
await で待ってあげる必要がある。(これをしないとTestIdが見つからないと怒られる)

TitleTest.spec.jsx
jest.mock("../supabaseClients.jsx", () => {
    let data = [ {id: 1, title: "dummy", time: 1}, {id: 2, title: "dummy2", time: 2} ];
    
    return {
        supabase: {
            from: jest.fn(() => ({
                select: jest.fn(() => {
                    return Promise.resolve({
                        data: data,
                        error: null,
                    })
                }),
                insert: jest.fn((newItem) => {
                    newItem.id = 2;
                    data = [...data, newItem];
                    return Promise.resolve({
                        data: newItem,
                        error: null,
                    });
                }),
                delete: jest.fn(() => {
                    return {                    
                        eq: jest.fn((key, value) => {
                        data = data.filter(item => item[key] !== value);
                        return Promise.resolve({
                            data: data,
                            error: null,
                        });
                    }),}
                }),
            })),
        },
    };
});


import { LearningRecord } from "../LearningRecord";
import React from "react";
import "@testing-library/jest-dom"
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";

describe("Title Test", () => {
    it("タイトルが学習記録一覧であること", async () => {
        render(<LearningRecord />);

        const title = await screen.findByTestId("title");
        expect(title).toHaveTextContent("学習記録一覧");
    });
});

(補足)

supabaseClients.jsx
import { createClient } from "@supabase/supabase-js";

//本番用
//const supabaseURL = import.meta.env.VITE_SUPABASE_URL;
//const supabaseKey = import.meta.env.VITE_SUPABASE_ANON_KEY;

//Jest テスト用
const supabaseURL = process.env.VITE_SUPABASE_URL;
const supabaseKey = process.env.VITE_SUPABASE_ANON_KEY;

export const supabase = createClient(supabaseURL, supabaseKey);

※import.metaはvite上の機能なので、下記記事を参考にしてvite.config.jsを次のように編集してJest上で.envファイルを読み取るようにした

vite.config.js
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import env from "vite-plugin-env-compatible"

// https://vite.dev/config/
export default defineConfig({
  plugins: [
    react(),
    env({ prefix: "VITE", mountedPath: "process.env" })
  ],
  base: "",
})

4 まとめ

supabaseや外部と通信する必要がある、テスト対象外の機能のに関してはmockを利用することが
必要である。
それぞれがどういった機能なのか、テスト対象は何かという事を考慮してあげるのが必要である。

JISOUのメンバー募集中!

プログラミングコーチングJISOUでは、新たなメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか?
興味のある方は、ぜひホームページをのぞいてみてくださ!
▼▼▼

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?