Expect
テストを作成する時に、値が特定の条件に合致することを確認する必要がよくあるでしょう。 expect
によって様々な事柄を検証するための数多くの「マッチャ」を利用することができます。
For additional Jest matchers maintained by the Jest Community check out jest-extended
.
このページの TypeScript の例は、次のように Jest の API を明示的にインポートした場合にのみ動作します。
import {expect, jest, test} from '@jest/globals';
TypeScript で Jest をセットアップする方法の詳細については、Getting Started ガイドを参照してください。
リファレンス
- Expect
- 修飾子
- Matchers
.toBe(value)
.toHaveBeenCalled()
.toHaveBeenCalledTimes(number)
.toHaveBeenCalledWith(arg1, arg2, ...)
.toHaveBeenLastCalledWith(arg1, arg2, ...)
.toHaveBeenNthCalledWith(nthCall, arg1, arg2, ....)
.toHaveReturned()
.toHaveReturnedTimes(number)
.toHaveReturnedWith(value)
.toHaveLastReturnedWith(value)
.toHaveNthReturnedWith(nthCall, value)
.toHaveLength(number)
.toHaveProperty(keyPath, value?)
.toBeCloseTo(number, numDigits?)
.toBeDefined()
.toBeFalsy()
.toBeGreaterThan(number | bigint)
.toBeGreaterThanOrEqual(number | bigint)
.toBeLessThan(number | bigint)
.toBeLessThanOrEqual(number | bigint)
.toBeInstanceOf(Class)
.toBeNull()
.toBeTruthy()
.toBeUndefined()
.toBeNaN()
.toContain(item)
.toContainEqual(item)
.toEqual(value)
.toMatch(regexp | string)
.toMatchObject(object)
.toMatchSnapshot(propertyMatchers?, hint?)
.toMatchInlineSnapshot(propertyMatchers?, inlineSnapshot)
.toStrictEqual(value)
.toThrow(error?)
.toThrowErrorMatchingSnapshot(hint?)
.toThrowErrorMatchingInlineSnapshot(inlineSnapshot)
- Asymmetric Matchers
expect.anything()
expect.any(constructor)
expect.arrayContaining(array)
expect.not.arrayContaining(array)
expect.arrayOf(value)
expect.not.arrayOf(value)
expect.closeTo(number, numDigits?)
expect.objectContaining(object)
expect.not.objectContaining(object)
expect.stringContaining(string)
expect.not.stringContaining(string)
expect.stringMatching(string | regexp)
expect.not.stringMatching(string | regexp)
- Assertion Count
- Extend Utilities
- Serializable properties
Expect
expect(value)
expect
は値をテストしたい時に毎回使用する関数です。 expect
のみを呼び出すということはほとんどありません。 代わりに、 値について何らかの事をアサートする"マッチャ"関数とともにexpect
を使用することでしょう。
この事は例を見れば簡単に理解できます。 'grapefruit'
という文字列を返すはずのbestLaCroixFlavor()
メソッドがあるとしましょう。 以下のようにテストするでしょう:
test('the best flavor is grapefruit', () => {
expect(bestLaCroixFlavor()).toBe('grapefruit');
});
このケースでは、 toBe
がマッチャ関数です。 様々な事をテストするのを手助けする数多くの異なるマッチャ関数があり、以下にまとめられています。
expect
への引数はコードが生成する値であるべきであり、いかなるマッチャへの引数は正解の値であるべきです。 それらを混同して使用すれば、テストは動作するものの、失敗したテストから出力されるエラーメッセージはおかしなものになります。
修飾子
.not
何かをテストする方法が分かっているなら、 .not
によってその反対の事をテストできます。 例えば以下のコード では、ラクロワ飲料で一番美味しいのはココナッツ味ではないことをテストでします。
test('the best flavor is not coconut', () => {
expect(bestLaCroixFlavor()).not.toBe('coconut');
});
.resolves
追加のマッチャをチェーンするためにに完了したpromiseの値を取り出すにはresolves
を使用して下さい。 promiseがrejectされた場合はアサーションは失敗します。
例えば、以下のコードではpromiseが完了した結果の値が'lemon'
であることをテストします:
test('resolves to lemon', () => {
// make sure to add a return statement
return expect(Promise.resolve('lemon')).resolves.toBe('lemon');
});
Promise をテストしているため、テストはまだ非同期です。 このために、ラップされていないアサーションを返すことで、Jest に処理が完了するまで待つように伝える必要があるのです。
また、async/await
を.resolves
と組み合わせて使うことができます。
test('resolves to lemon', async () => {
await expect(Promise.resolve('lemon')).resolves.toBe('lemon');
await expect(Promise.resolve('lemon')).resolves.not.toBe('octopus');
});
.rejects
追加のマッチャをチェーンするためににrejectされたpromiseの理由を取り出すには .rejects
を使用して下さい。 promiseが完了した場合はアサーションは失敗します。
たとえば、このコードは Promise が 'octopus'
という理由で reject されたことをテストします。
test('rejects to octopus', () => {
// make sure to add a return statement
return expect(Promise.reject(new Error('octopus'))).rejects.toThrow(
'octopus',
);
});
Promise をテストしているため、テストはまだ非同期です。 このために、ラップされていないアサーションを返すことで、Jest に処理が完了するまで待つように伝える必要があるのです。
また、async/await
を.rejects
と組み合わせて使うことができます。
test('rejects to octopus', async () => {
await expect(Promise.reject(new Error('octopus'))).rejects.toThrow('octopus');
});
Matchers
.toBe(value)
プリミティブ値を比較したり、オブジェクトインスタンスの参照IDを確認したりするには、 .toBe
を使用します。 It calls Object.is
to compare values, which is even better for testing than ===
strict equality operator.
例えば以下のコードでは can
オブジェクトのいくつかのプロパティを検証します。
const can = {
name: 'pamplemousse',
ounces: 12,
};
describe('the can', () => {
test('has 12 ounces', () => {
expect(can.ounces).toBe(12);
});
test('has a sophisticated name', () => {
expect(can.name).toBe('pamplemousse');
});
});
浮動小数点数に .toBe
を使用しないでください。 例えば、JavaScriptでは数値の丸めによって0.2 + 0.1
と 0.3
は厳密には等価ではありません。 浮動小数点がある場合は、代わりに.toBeCloseTo
を使用してください。
.toBe
マッチャー は 参照IDをチェックしますが、アサーションが失敗した場合、 値の再帰的な比較を** 報告します**。 特にレポートが大きい場合には、プロパティ間の差分は、テストが失敗する理原因を解明することに寄与しません。 そうすると、比較処理を expect
関数の中に移すことでしょう 例えば、要素が同じインスタンスであるかどうかをアサートするには、次のようにします。
- rewrite
expect(received).toBe(expected)
asexpect(Object.is(received, expected)).toBe(true)
- rewrite
expect(received).not.toBe(expected)
asexpect(Object.is(received, expected)).toBe(false)
.toHaveBeenCalled()
Use .toHaveBeenCalled
to ensure that a mock function was called.
For example, let's say you have a drinkAll(drink, flavour)
function that takes a drink
function and applies it to all available beverages. You might want to check that drink
gets called. このテストスイートでテストすることができます:
function drinkAll(callback, flavour) {
if (flavour !== 'octopus') {
callback(flavour);
}
}
describe('drinkAll', () => {
test('drinks something lemon-flavoured', () => {
const drink = jest.fn();
drinkAll(drink, 'lemon');
expect(drink).toHaveBeenCalled();
});
test('does not drink something octopus-flavoured', () => {
const drink = jest.fn();
drinkAll(drink, 'octopus');
expect(drink).not.toHaveBeenCalled();
});
});
.toHaveBeenCalledTimes(number)
モック関数が期待した回数だけ呼ばれたことを確認するには.toHaveBeenCalledTimes
を使用して下さい。
例えばdrink
関数を引数に取って渡された飲み物の配列に適用する drinkEach(drink, Array<flavor>)
関数があるとしましょう。 drink関数が正しい回数だけ呼ばれたことを確認したいでしょう。 このテストスイートでテストすることができます:
test('drinkEach drinks each drink', () => {
const drink = jest.fn();
drinkEach(drink, ['lemon', 'octopus']);
expect(drink).toHaveBeenCalledTimes(2);
});
.toHaveBeenCalledWith(arg1, arg2, ...)
モック関数が特定の引数を与えられて呼び出されたことを確認するには .toHaveBeenCalledWith
を使用して下さい。 The arguments are checked with the same algorithm that .toEqual
uses.
例えば register
関数で飲み物を登録でき、applyToAll(f)
は 関数f
を全ての登録された飲み物に適用するものとしましょう。 この振る舞いを確認するコードは、下記のように書けるでしょう:
test('registration applies correctly to orange La Croix', () => {
const beverage = new LaCroix('orange');
register(beverage);
const f = jest.fn();
applyToAll(f);
expect(f).toHaveBeenCalledWith(beverage);
});
.toHaveBeenLastCalledWith(arg1, arg2, ...)
モック関数がある場合は .toHaveBeenLastCalledWith
を使用して、最後の呼び出しがどんな引数を渡されたかをテストすることができます。 例えば 複数の風味に対して関数f
を適用するapplyToAllFlavors(f)
関数があり、関数fが最後に操作した風味が'mango'
だったとしましょう。 以下のようにテストコードを書くことができます。
test('applying to all flavors does mango last', () => {
const drink = jest.fn();
applyToAllFlavors(drink);
expect(drink).toHaveBeenLastCalledWith('mango');
});
.toHaveBeenNthCalledWith(nthCall, arg1, arg2, ....)
あるモック関数があるとき、.toHaveReturned
を使用すると、モック関数が正しく (つまり、例外が発生せずに) 変えることをテストできます。 たとえば、true
を返すモック関数 drink
があるとすると、テストは次のように書くことができます。 以下のようにテストコードを書くことができます。
test('drink は n 回目の呼び出しで期待した値を返す', () => {
const beverage1 = {name: 'La Croix (レモン)'};
const beverage2 = {name: 'La Croix (オレンジ)'};
const drink = jest.fn(beverage => beverage.name);
drink(beverage1);
drink(beverage2);
expect(drink).toHaveNthReturnedWith(1, 'La Croix (レモン)');
expect(drink).toHaveNthReturnedWith(2, 'La Croix (オレンジ)');
});
The nth argument must be positive integer starting from 1.
.toHaveReturned()
あるモック関数があるとき、.toHaveReturned
を使用すると、モック関数が正しく (つまり、例外が発生せずに) 変えることをテストできます。 たとえば、true
を返すモック関数 drink
があるとすると、テストは次のように書くことができます。 以下のようにテストコードを書くことができます。
test('drinkEach drinks each drink', () => {
const drink = jest.fn();
drinkEach(drink, ['レモン', 'タコ']);
expect(drink).toHaveBeenNthCalledWith(1, 'レモン');
expect(drink).toHaveBeenNthCalledWith(2, 'タコ');
});