モック関数
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 リファレンスでは、モックの動作を操作するために利用可能なプロパティとメソッドについて説明します。
getMockImplementation
- 型:
(...args: any) => any
現在のモックの実装が存在する場合、その実装を返します。
モックが vi.fn
で作成された場合、渡された関数がモックの実装とみなされます。
モックが vi.spyOn
で作成された場合、カスタム実装が提供されない限り、undefined
を返します。
getMockName
- 型:
() => string
.mockName(name)
メソッドでモックに設定された名前を返すために使用します。
mockClear
- 型:
() => MockInstance
すべての呼び出しに関する情報をクリアします。このメソッドを呼び出すと、.mock
のすべてのプロパティが初期状態に戻ります。このメソッドは実装をリセットしません。異なるアサーション間でモックをクリアする必要がある場合に役立ちます。
このメソッドを各テストの前に自動的に呼び出す場合は、設定で clearMocks
を有効にできます。
mockName
- 型:
(name: string) => MockInstance
内部モック名を設定します。アサーションが失敗した場合に、モックの名前を確認するのに役立ちます。
mockImplementation
- 型:
(fn: Function) => MockInstance
モックの実装として使用される関数を受け取ります。
import { vi } from 'vitest';
// ---cut---
const 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
次の呼び出し時にモックの実装として使用される関数を受け取ります。複数の関数呼び出しが異なる結果を生成するように、メソッドチェーンで設定できます。
import { vi } from 'vitest';
// ---cut---
const myMockFn = vi
.fn()
.mockImplementationOnce(() => true)
.mockImplementationOnce(() => false);
myMockFn(); // true
myMockFn(); // false
モックされた関数が実装を使い果たした場合、vi.fn(() => defaultValue)
または .mockImplementation(() => defaultValue)
で設定されたデフォルトの実装を呼び出します(設定されている場合)。
import { vi } from 'vitest';
// ---cut---
const 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>
コールバックの実行中に、一時的に元のモックの実装をオーバーライドします。
import { vi } from 'vitest';
// ---cut---
const myMockFn = vi.fn(() => 'original');
myMockFn.withImplementation(
() => 'temp',
() => {
myMockFn(); // 'temp'
}
);
myMockFn(); // 'original'
非同期コールバックでも使用できます。後で元の実装を使用するには、メソッドの完了を待つ必要があります。
test('async callback', () => {
const myMockFn = vi.fn(() => 'original');
// コールバックが非同期処理のため、この呼び出しを await します
await myMockFn.withImplementation(
() => 'temp',
async () => {
myMockFn(); // 'temp'
}
);
myMockFn(); // 'original'
});
このメソッドは、mockImplementationOnce
よりも優先されることに注意してください。
mockRejectedValue
- 型:
(value: any) => MockInstance
非同期関数が呼び出されたときに reject されるエラーを受け取ります。
import { vi } from 'vitest';
// ---cut---
const asyncMock = vi.fn().mockRejectedValue(new Error('Async error'));
await asyncMock(); // throws "Async error"
mockRejectedValueOnce
- 型:
(value: any) => MockInstance
次の関数呼び出し時に reject される値を受け取ります。メソッドチェーンで設定されている場合、後続の呼び出しは指定された値で reject されます。
import { vi } from 'vitest';
// ---cut---
const asyncMock = vi
.fn()
.mockResolvedValueOnce('first call')
.mockRejectedValueOnce(new Error('Async error'));
await asyncMock(); // 'first call'
await asyncMock(); // throws "Async error"
mockReset
- 型:
() => MockInstance
mockClear
と同じように、すべての呼び出しに関する情報をクリアし、内部実装を空の関数にします(呼び出されると undefined
を返します)。これにより、すべての「once」実装もリセットされます。モックを完全にデフォルトの状態にリセットする場合に役立ちます。
このメソッドを各テストの前に自動的に呼び出す場合は、設定で mockReset
を有効にできます。
mockRestore
- 型:
() => MockInstance
mockReset
と同じように、すべての呼び出しに関する情報をクリアし、内部実装を元の関数に復元します。
vi.fn()
からモックを復元すると、実装が undefined
を返す空の関数に設定されることに注意してください。vi.fn(impl)
を復元すると、実装が impl
に復元されます。
このメソッドを各テストの前に自動的に呼び出す場合は、設定で restoreMocks
を有効にできます。
mockResolvedValue
- 型:
(value: any) => MockInstance
非同期関数が呼び出されたときに resolve される値を受け取ります。
import { vi } from 'vitest';
// ---cut---
const asyncMock = vi.fn().mockResolvedValue(42);
await asyncMock(); // 42
mockResolvedValueOnce
- 型:
(value: any) => MockInstance
次の関数呼び出し時に resolve される値を受け取ります。メソッドチェーンで設定されている場合、後続のすべての呼び出しは指定された値を resolve します。
import { vi } from 'vitest';
// ---cut---
const 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
コンテキストを返す必要がある場合に使用します。これは、次のコードの省略形です。
spy.mockImplementation(function () {
return this;
});
mockReturnValue
- 型:
(value: any) => MockInstance
モック関数が呼び出されるたびに返される値を受け取ります。
import { vi } from 'vitest';
// ---cut---
const mock = vi.fn();
mock.mockReturnValue(42);
mock(); // 42
mock.mockReturnValue(43);
mock(); // 43
mockReturnValueOnce
- 型:
(value: any) => MockInstance
次の関数呼び出し時に返される値を受け取ります。メソッドチェーンで設定されている場合、後続のすべての呼び出しは指定された値を返します。
使用する mockReturnValueOnce
の値がなくなった場合、モックは以前に定義された実装(存在する場合)に戻ります。
import { vi } from 'vitest';
// ---cut---
const 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');
fn.mock.calls ===
[
['arg1', 'arg2'], // 1回目の呼び出し
['arg3'], // 2回目の呼び出し
];
mock.lastCall
これには、最後の呼び出しの引数が含まれています。モックが一度も呼び出されていない場合は、undefined
を返します。
mock.results
これは、関数から返されたすべての値を含む配列です。配列の各要素は、type
プロパティと value
プロパティを持つオブジェクトです。利用可能なタイプは次のとおりです。
'return'
- 関数は例外をスローせずに正常に終了しました。'throw'
- 関数は値をスローしました。
value
プロパティには、返された値またはスローされたエラーが含まれています。関数が Promise を返した場合、value
は、解決されなかった場合を除き、実際の Promise
ではなく、解決された 値になります。
const fn = vi
.fn()
.mockReturnValueOnce('result')
.mockImplementationOnce(() => {
throw new Error('thrown error');
});
const result = fn(); // resultを返しました
try {
fn(); // Errorをスローしました
} catch {}
fn.mock.results ===
[
// first result
{
type: 'return',
value: 'result',
},
// last result
{
type: 'throw',
value: Error,
},
];
mock.invocationCallOrder
モックの実行順序を示す数値の配列です。これは、定義されたすべてのモック間で共有されます。
const fn1 = vi.fn();
const fn2 = vi.fn();
fn1();
fn2();
fn1();
fn1.mock.invocationCallOrder === [1, 3];
fn2.mock.invocationCallOrder === [2];
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;