モック関数
vi.fn
メソッドを使用すると、その実行を追跡するためのモック関数(スパイ)を作成できます。既存のオブジェクトのメソッドを追跡する場合は、vi.spyOn
メソッドを使用できます。
import { vi } from 'vitest';
const fn = vi.fn();
fn('hello world');
fn.mock.calls[0] === ['hello world'];
const market = {
getApples: () => 100,
};
const getApplesSpy = vi.spyOn(market, 'getApples');
market.getApples();
getApplesSpy.mock.calls.length === 1;
スパイの結果をアサートするには、expect
でスパイのアサーション(例えば、toHaveBeenCalled
)を使用する必要があります。この API リファレンスでは、スパイの動作を操作するために利用可能なプロパティとメソッドについて説明します。
getMockName
型:
() => string
.mockName(name)
メソッドでモックに設定された名前を返すために使用します。
mockClear
型:
() => MockInstance
すべての呼び出しに関する情報をクリアします。このメソッドを呼び出すと、
spy.mock.calls
、spy.mock.results
は空の配列を返します。異なるアサーション間でスパイを初期化する必要がある場合に便利です。このメソッドを各テストの前に自動的に呼び出すようにするには、設定で
clearMocks
を有効にできます。
mockName
型:
(name: string) => MockInstance
モックの内部名を設定します。どのアサーションが失敗したかを特定するのに役立ちます。
mockImplementation
型:
(fn: Function) => MockInstance
モックの実装として使用する関数を受け取ります。
例:
tsconst mockFn = vi.fn().mockImplementation(apples => apples + 1); // または: vi.fn(apples => apples + 1); const NelliesBucket = mockFn(0); const BobsBucket = mockFn(1); NelliesBucket === 1; // true BobsBucket === 2; // true mockFn.mock.calls[0][0] === 0; // true mockFn.mock.calls[1][0] === 1; // true
mockImplementationOnce
型:
(fn: Function) => MockInstance
モック関数が 1 回呼び出されるごとに、モックの実装として使用される関数を受け取ります。複数の関数呼び出しが異なる結果を生成するように、メソッドチェーンで設定できます。
tsconst myMockFn = vi .fn() .mockImplementationOnce(() => true) .mockImplementationOnce(() => false); myMockFn(); // true myMockFn(); // false
モック関数が実装を使い果たすと、
vi.fn(() => defaultValue)
または.mockImplementation(() => defaultValue)
で設定されたデフォルトの実装を呼び出します(設定されている場合)。tsconst myMockFn = vi .fn(() => 'default') .mockImplementationOnce(() => 'first call') .mockImplementationOnce(() => 'second call'); // 'first call', 'second call', 'default', 'default' console.log(myMockFn(), myMockFn(), myMockFn(), myMockFn());
withImplementation
型:
(fn: Function, callback: () => void) => MockInstance
型:
(fn: Function, callback: () => Promise<unknown>) => Promise<MockInstance>
コールバックが実行されている間、一時的に元のモックの実装をオーバーライドします。
jsconst myMockFn = vi.fn(() => 'original'); myMockFn.withImplementation( () => 'temp', () => { myMockFn(); // 'temp' } ); myMockFn(); // 'original'
非同期コールバックでも使用できます。元の実装に戻すには、このメソッドの完了を待つ必要があります。
tstest('async callback', () => { const myMockFn = vi.fn(() => 'original'); // コールバックが非同期関数であるため、この呼び出しを await します await myMockFn.withImplementation( () => 'temp', async () => { myMockFn(); // 'temp' } ); myMockFn(); // 'original' });
また、
mockImplementationOnce
よりも優先されます。
mockRejectedValue
型:
(value: any) => MockInstance
非同期関数が呼び出された時に reject されるエラーを設定します。
tsconst asyncMock = vi.fn().mockRejectedValue(new Error('Async error')); await asyncMock(); // "Async error" エラーをスロー
mockRejectedValueOnce
型:
(value: any) => MockInstance
モック関数が 1 回呼び出されるごとにリジェクトされる値を受け入れます。メソッドチェーンで設定すると、連続する呼び出しごとに指定された値で reject します。
tsconst asyncMock = vi .fn() .mockRejectedValueOnce('first call') .mockRejectedValueOnce(new Error('Async error')); await asyncMock(); // first call await asyncMock(); // "Async error" エラーをスロー
mockReset
型:
() => MockInstance
mockClear
と同じように、すべての呼び出しに関する情報をクリアし、さらに内部実装を空の関数にリセットします(呼び出されたときにundefined
を返します)。これは、モックを完全に初期状態にリセットする場合に便利です。このメソッドを各テストの前に自動的に呼び出すようにするには、設定で
mockReset
を有効にできます。
mockRestore
型:
() => MockInstance
mockReset
と同じように、すべての呼び出しに関する情報をクリアし、さらに内部実装を元の関数に戻します。vi.fn()
からモックを復元すると、実装がundefined
を返す空の関数に設定されることに注意してください。vi.fn(impl)
を復元すると、実装がimpl
に復元されます。このメソッドを各テストの前に自動的に呼び出すようにするには、設定で
restoreMocks
を有効にできます。
mockResolvedValue
型:
(value: any) => MockInstance
非同期関数が呼び出されたときに解決される値を受け入れます。
tsconst asyncMock = vi.fn().mockResolvedValue(43); await asyncMock(); // 43
mockResolvedValueOnce
型:
(value: any) => MockInstance
モック関数が 1 回呼び出されるごとに解決される値を受け入れます。メソッドチェーンで設定されている場合、連続するすべての呼び出しは渡された値を解決します。
tsconst asyncMock = vi .fn() .mockResolvedValue('default') .mockResolvedValueOnce('first call') .mockResolvedValueOnce('second call'); await asyncMock(); // first call await asyncMock(); // second call await asyncMock(); // default await asyncMock(); // default
mockReturnThis
型:
() => MockInstance
内部実装を
this
コンテキストを返すように設定します。
mockReturnValue
型:
(value: any) => MockInstance
モック関数が呼び出されるたびに返される値を受け入れます。
tsconst mock = vi.fn(); mock.mockReturnValue(42); mock(); // 42 mock.mockReturnValue(43); mock(); // 43
mockReturnValueOnce
型:
(value: any) => MockInstance
モック関数が 1 回呼び出されるごとに返される値を受け入れます。メソッドチェーンで設定されている場合、連続するすべての呼び出しは渡された値を返します。使用する
mockReturnValueOnce
の値がなくなった場合、mockImplementation
または他のmockReturn*
メソッドで指定された関数を呼び出します。tsconst myMockFn = vi .fn() .mockReturnValue('default') .mockReturnValueOnce('first call') .mockReturnValueOnce('second call'); // 'first call', 'second call', 'default', 'default' console.log(myMockFn(), myMockFn(), myMockFn(), myMockFn());
mock.calls
これは、各呼び出しのすべての引数を含む配列です。配列の各要素は、その呼び出しの引数の配列です。
const fn = vi.fn();
fn('arg1', 'arg2');
fn('arg3', 'arg4');
fn.mock.calls ===
[
['arg1', 'arg2'], // 最初の呼び出し
['arg3', 'arg4'], // 2回目の呼び出し
];
mock.lastCall
これには、最後の呼び出しの引数が含まれています。スパイが呼び出されなかった場合は、undefined
を返します。
mock.results
これは、関数から返却されたすべての値を含む配列です。配列の各要素は、プロパティ type
と value
を持つオブジェクトです。利用可能なタイプは次のとおりです。
'return'
- 関数は例外をスローせずに正常に返されました。'throw'
- 関数は値をスローしました。
value
プロパティには、返された値またはスローされたエラーが含まれています。関数が Promise を返した場合、解決されると value
プロパティは Promise が解決された値になります。
const fn = vi.fn();
const result = fn(); // 'result' を返しました
try {
fn(); // Error をスローしました
} catch {}
fn.mock.results ===
[
// 最初の結果
{
type: 'return',
value: 'result',
},
// 最後の結果
{
type: 'throw',
value: Error,
},
];
mock.instances
これは、モックが new
キーワードで呼び出された際に生成されたすべてのインスタンスを格納する配列です。これは関数の実際のコンテキスト(this
)であり、戻り値そのものではないことに注意してください。
WARNING
モックが new MyClass()
でインスタンス化された場合、mock.instances
は 1 つの値を持つ配列になります。
const MyClass = vi.fn();
const a = new MyClass();
MyClass.mock.instances[0] === a;
コンストラクターから値を返す場合、それは instances
配列には格納されず、代わりに results
に格納されます。
const Spy = vi.fn(() => ({ method: vi.fn() }));
const a = new Spy();
Spy.mock.instances[0] !== a;
Spy.mock.results[0] === a;