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?

VitestでSupabaseを使うテストがCI環境だけ落ちる問題の対処法

1
Posted at

はじめに

ローカルではちゃんと通るテストが、GitHub Actionsだとエラーで落ちるという経験をしました。

Error: supabaseUrl is required.
 ❯ validateSupabaseUrl ...
 ❯ new SupabaseClient ...
 ❯ createClient ...
 ❯ src/lib/supabase.ts:7:25
 ❯ src/services/studyRecords.ts:1:1

vi.mock でモックしてるのになぜ?と最初は混乱しましたが、原因を理解したらすっきり解決できたので書き残しておきます。

なぜ起きるのか

構造の確認

まず問題になったコードの構造はこんな感じです。

// src/lib/supabase.ts
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
const supabaseKey = import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY;
export const supabase = createClient<Database>(supabaseUrl, supabaseKey);
// src/services/studyRecords.ts
import { supabase } from '../lib/supabase'; // このimportがsupabase.tsを実行する
// テストファイル
vi.mock("../services/studyRecords"); // ファクトリなし

ファクトリとは

vi.mock の第2引数として渡せる関数のことです。

// ファクトリなし(自動モック)
vi.mock("../services/studyRecords");

// ファクトリあり(手動でモックの中身を定義)
vi.mock("../services/studyRecords", () => ({
  fetchRecords: vi.fn().mockResolvedValue({ data: 'default data' }),
  saveRecord: vi.fn(),
}));

ファクトリを渡すと、Vitestは実モジュールを読み込まずに「この関数が返したオブジェクトをモックとして使う」ため、supabase.ts は一切実行されません。

vi.mock があっても失敗する理由

ポイントは ファクトリなしの vi.mock の挙動 です。

vi.mock("../services/studyRecords") をファクトリなしで呼ぶと、Vitestは実際のモジュールを一度ロードしてエクスポートを解析し、そこから自動モックを生成します。

このロード時に supabase.ts も実行されるため、createClient(undefined, undefined) が呼ばれてエラーになるわけです。

ローカルでは .env ファイル(gitignored)に VITE_SUPABASE_URL が設定されているので通りますが、CI環境にはそのファイルがないため失敗します。「ローカルだけ通る」の正体はこれでした。

解決策:vite.config.ts でダミー値を注入する

vite.config.tstest セクションに env を追加して、テスト実行時に常にダミー値を提供するようにします。

test: {
  env: {
    VITE_SUPABASE_URL: 'https://placeholder.supabase.co',
    VITE_SUPABASE_PUBLISHABLE_KEY: 'placeholder-key',
  },
},

これだけです。ダミー値があれば createClient のインスタンス化は通ります。テスト内では studyRecords がモックされているため、実際にSupabaseへ接続することはありません。

まとめ・学んだこと

  • vi.mock(path) はファクトリなしだと実モジュールをロードするため、モジュールレベルの副作用(APIクライアントの初期化など)は回避できない
  • 環境変数に依存するモジュールレベルの初期化は、テスト環境で壊れやすい
  • 対策は2つで、
    • vite.config.tstest.env でダミー値を注入する(今回の方法)
    • vi.mock にファクトリを渡してモジュールロードを完全に置き換える
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?