0
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】vi.hoisted——モック関数などを先に用意する

0
Posted at

はじめに

この投稿は、学習の備忘録として書いています。vi.mockのファクトリから参照したいモック関数などを先に用意するvi.hoistedを整理します。動作を確認したバージョンはVitest 5.0.2です。

1. vi.mockの巻き上げ

vi.mockは、ファイルの先頭へ巻き上げられてから実行されます。そのため、あとに書いた変数をファクトリから参照すると、初期化前の参照になります。

import { expect, it, vi } from "vitest";

const saveMock = vi.fn();

vi.mock("./api", () => ({
  save: saveMock,
}));

この並びだと、次のようなエラーになります。

Error: [vitest] There was an error when mocking a module. If you are using "vi.mock" factory, make sure there are no top level variables inside, since this call is hoisted to top of the file.
Caused by: ReferenceError: Cannot access 'saveMock' before initialization

巻き上げられた時点では、const saveMockはまだ実行されていません。

2. vi.hoistedがすること

vi.hoistedに渡した関数は、vi.mockより前に実行されます。そこでvi.fn()を作り、ファクトリから参照します。

import { vi } from "vitest";

const { saveMock } = vi.hoisted(() => ({
  saveMock: vi.fn(),
}));

vi.mock("./api", () => ({
  save: saveMock,
}));

ファクトリが走る時点では、すでにsaveMockがあります。

3. テスト本体での使い方

作ったsaveMockは、テスト側で操作します。mockResetで呼び出し記録を消し、mockResolvedValueで戻り値を決めます。

import { beforeEach, expect, it, vi } from "vitest";

const { saveMock } = vi.hoisted(() => ({
  saveMock: vi.fn(),
}));

vi.mock("./api", () => ({
  save: saveMock,
}));

import { save } from "./api";

beforeEach(() => {
  saveMock.mockReset();
});

it("returns the resolved value", async () => {
  saveMock.mockResolvedValue("ok");
  await expect(save("x")).resolves.toBe("ok");
});

import { save } from "./api"が読むsaveは、ファクトリが返したsaveMockです。テスト内のsave("x")は、そのモック関数を呼んでいます。

まとめ

  • vi.mockはファイル先頭に巻き上げられるため、あとに書いた変数をファクトリから参照できません。
  • vi.hoistedに渡した関数はvi.mockより前に実行されるので、そこで作ったモック関数などをファクトリから参照できます。
0
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
0
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?