テストモジュールの開発中、汚染を防ぐおまじないの如く、afterEachにrestoreAllMocksを入れていたところ上手く動かなくなることがあったため、違いをメモ。
clear
役割:呼び出し履歴を消す。モックの挙動(Implementation,ReturnValue等)は残る。
用途:同じモックを複数のテストケースで再利用する時。
const fn = vi.fn().mockReturnValue("foo");
fn();
expect(fn).toHaveBeenCalledTimes(1);
fn.mockClear(); // 呼び出し履歴だけリセット
expect(fn).toHaveBeenCalledTimes(0); // ← 0回に戻る
expect(fn()).toBe("foo"); // ← 実装は残ってる
reset
役割:履歴を消す+モックの挙動を空にする。モックを呼び出すとundefinedを返す。
用途:テスト毎にモックの挙動を変えたい場合。
const fn = vi.fn().mockReturnValue("foo");
fn();
expect(fn).toHaveBeenCalledTimes(1);
fn.mockReset(); // 履歴も実装もリセット
expect(fn).toHaveBeenCalledTimes(0);
expect(fn()).toBeUndefined(); // ← "foo"じゃなくなる
restore
役割:履歴を消す+モックの挙動を元に戻す。例えばDate.now()をモック化していたら、restoreで元通り日付時刻を返すようになる。vi.fn()はundefinedになるのでresetと変わらない。
用途:一時的にモックして元に戻したい場合、他のテストに影響を与えないための後片付け。
const obj = {
greet: () => "hello",
};
const spy = vi.spyOn(obj, "greet").mockReturnValue("mocked");
expect(obj.greet()).toBe("mocked");
spy.mockRestore(); // 元の関数に戻す
expect(obj.greet()).toBe("hello");
vi.mock等には基本的にclearかresetでrestoreする必要はない。
逆にグローバルを弄るテストはvi.restoreで元に戻す。