Expect
When you're writing tests, you often need to check that values meet certain conditions. expect
gives you access to a number of "matchers" that let you validate different things.
For additional Jest matchers maintained by the Jest Community check out jest-extended
.
メソッド
expect(value)
expect.extend(matchers)
expect.anything()
expect.any(constructor)
expect.arrayContaining(array)
expect.assertions(number)
expect.hasAssertions()
expect.objectContaining(object)
expect.stringContaining(string)
expect.stringMatching(regexp)
expect.addSnapshotSerializer(serializer)
.not
.resolves
.rejects
.toBe(value)
.toHaveBeenCalled()
.toHaveBeenCalledTimes(number)
.toHaveBeenCalledWith(arg1, arg2, ...)
.toHaveBeenLastCalledWith(arg1, arg2, ...)
.toHaveLength(number)
.toHaveProperty(keyPath, value)
.toBeCloseTo(number, numDigits)
.toBeDefined()
.toBeFalsy()
.toBeGreaterThan(number)
.toBeGreaterThanOrEqual(number)
.toBeLessThan(number)
.toBeLessThanOrEqual(number)
.toBeInstanceOf(Class)
.toBeNull()
.toBeTruthy()
.toBeUndefined()
.toBeNaN()
.toContain(item)
.toContainEqual(item)
.toEqual(value)
.toMatch(regexpOrString)
.toMatchObject(object)
.toMatchSnapshot(optionalString)
.toThrow(error)
.toThrowErrorMatchingSnapshot()
リファレンス
expect(value)
expect
は値をテストしたい時に毎回使用する関数です。 expect
のみを呼び出すということはほとんどありません。 代わりに、 値について何らかの事をアサートする"マッチャ"関数とともにexpect
を使用することでしょう。
この事は例を見れば簡単に理解できます。 'grapefruit'
という文字列を返すはずのbestLaCroixFlavor()
メソッドがあるとしましょう。 以下のようにテストするでしょう:
test('the best flavor is grapefruit', () => {
expect(bestLaCroixFlavor()).toBe('grapefruit');
});
In this case, toBe
is the matcher function. There are a lot of different matcher functions, documented below, to help you test different things.
expect
への引数はコードが生成する値であるべきであり、いかなるマッチャへの引数は正解の値であるべきです。 それらを混同して使用すれば、テストは動作するものの、失敗したテストから出力されるエラーメッセージはおかしなものになります。
expect.extend(matchers)
Jestに独自のマッチャを追加したい場合は expect.extend
を使用します。 例えば、整数論のライブラリをテストしていて、数字が他の数字によって割り切れることを頻繁にアサートしているとしましょう。 それをtoBeDivisibleBy
マッチャに抽象化することができます:
expect.extend({
toBeDivisibleBy(received, argument) {
const pass = received % argument == 0;
if (pass) {
return {
message: () =>
`expected ${received} not to be divisible by ${argument}`,
pass: true,
};
} else {
return {
message: () => `expected ${received} to be divisible by ${argument}`,
pass: false,
};
}
},
});
test('even and odd numbers', () => {
expect(100).toBeDivisibleBy(2);
expect(101).not.toBeDivisibleBy(2);
});
Note: In TypeScript, when using @types/jest
for example, you can declare the new toBeWithinRange
matcher like this:
declare global {
namespace jest {
interface Matchers<R> {
toBeWithinRange(a: number, b: number): R;
}
}
}
マッチャ は、2つのキーを持つオブジェクトを返す必要があります。 pass
キーはマッチャの条件に合致するかどうかを示し、 message
キーは失敗した場合にエラーメッセージを返す引数なしの関数を提供します。 したがって、pass
が偽なら、 message
はexpect(x).yourMatcher()
が失敗した場合のエラーメッセージを返す必要があります。 pass
が真だった場合、 message
はexpect(x).not.yourMatcher()
が失敗した場合のエラーメッセージを返す必要があります。
These helper functions and properties can be found on this
inside a custom matcher:
this.isNot
マッチャがアサーションを反転させる否定の修飾子 .not
を付けて呼ばれたかどうかを示す真偽値です。
this.equals(a, b)
2つのオブジェクトが同じ値を(再帰的に) 持つ場合に true
を返す深い等価関数です。
this.expand
A boolean to let you know this matcher was called with an expand
option. When Jest is called with the --expand
flag, this.expand
can be used to determine if Jest is expected to show full diffs and errors.
this.utils
jest-matcher-utils
からexportされたもので主に構成されるthis.utils
から利用できる多数の便利なツールがあります。
最も有用なものにエラーメッセージを見やすくフォーマットする matcherHint
、 printExpected
そしてprintReceived
があります。 例えば、 toBe
マッチャの実装を見てみましょう:
const diff = require('jest-diff');
expect.extend({
toBe(received, expected) {
const pass = Object.is(received, expected);
const message = pass
? () =>
this.utils.matcherHint('.not.toBe') +
'\n\n' +
`Expected value to not be (using Object.is):\n` +
` ${this.utils.printExpected(expected)}\n` +
`Received:\n` +
` ${this.utils.printReceived(received)}`
: () => {
const diffString = diff(expected, received, {
expand: this.expand,
});
return (
this.utils.matcherHint('.toBe') +
'\n\n' +
`Expected value to be (using Object.is):\n` +
` ${this.utils.printExpected(expected)}\n` +
`Received:\n` +
` ${this.utils.printReceived(received)}` +
(diffString ? `\n\nDifference:\n\n${diffString}` : '')
);
};
return {actual: received, message, pass};
},
});
上記のコードはこのような出力をします:
expect(received).toBe(expected)
Expected value to be (using Object.is):
"banana"
Received:
"apple"
アサーションに失敗した場合、エラーメッセージは利用者がその問題を迅速に解決できるようになるべく多くのシグナルを与えるものであるべきです。 独自アサーションの利用者が良い開発体験を得られるよう正確なエラーメッセージを作成する必要があります。
expect.anything()
expect.anything()
は、null
または undefined
を除くものすべてに一致します。 toEqual
または toBeCalledWith
の内側でリテラル値の代わりに使用できます。 例えば、モック関数がnullでない引数を与えられて呼び出されたことを確認するには:
test('map calls its argument with a non-null argument', () => {
const mock = jest.fn();
[1].map(x => mock(x));
expect(mock).toBeCalledWith(expect.anything());
});
expect.any(constructor)
expect.any(constructor)
は与えられたコンストラクタで生成されたもの全てに一致します。 toEqual
または toBeCalledWith
の内側でリテラル値の代わりに使用できます。 例えば、モック関数が数字の引数を与えられて呼び出されたことを確認するには:
function randocall(fn) {
return fn(Math.floor(Math.random() * 6 + 1));
}
test('randocall calls its callback with a number', () => {
const mock = jest.fn();
randocall(mock);
expect(mock).toBeCalledWith(expect.any(Number));
});
expect.arrayContaining(array)
expect.arrayContaining(array)
は受け取った配列が期待される配列の要素全てを含む場合に一致します。 つまり受け取った配列は期待される配列を 包含 するということです。 したがって受け取る配列が期待される配列に含まれない要素を含んでいても一致します。
以下のケースでリテラル値の代わりに使用できます:
toEqual
またはtoBeCalledWith
の中objectContaining
またはtoMatchObject
のプロパティとマッチさせる場合
describe('arrayContaining', () => {
const expected = ['Alice', 'Bob'];
it('matches even if received contains additional elements', () => {
expect(['Alice', 'Bob', 'Eve']).toEqual(expect.arrayContaining(expected));
});
it('does not match if received does not contain expected elements', () => {
expect(['Bob', 'Eve']).not.toEqual(expect.arrayContaining(expected));
});
});
describe('Beware of a misunderstanding! A sequence of dice rolls', () => {
const expected = [1, 2, 3, 4, 5, 6];
it('matches even with an unexpected number 7', () => {
expect([4, 1, 6, 7, 3, 5, 2, 5, 4, 6]).toEqual(
expect.arrayContaining(expected),
);
});
it('does not match without an expected number 2', () => {
expect([4, 1, 6, 7, 3, 5, 7, 5, 4, 6]).not.toEqual(
expect.arrayContaining(expected),
);
});
});
expect.assertions(number)
expect.assertions(number)
はテスト中に特定の数だけアサーションが呼び出されたことを確認します。 非同期のコードをテストにおいて、コールバック中のアサーションが実際に呼ばれたことを確認する際にしばしば便利です。
例えば、 callback1
と callback2
の2つのコールバックを受けとるdoAsync
関数があったとしたら、その関数は未知の順序で両方を呼び出します。 以下のコードでテストできます:
test('doAsync calls both callbacks', () => {
expect.assertions(2);
function callback1(data) {
expect(data).toBeTruthy();
}
function callback2(data) {
expect(data).toBeTruthy();
}
doAsync(callback1, callback2);
});
expect.assertions(2)
を呼び出すことで両方のコールバックが実際に呼ばれたことを確認できます。
expect.hasAssertions()
expect.hasAssertions()
はテスト中で少なくとも1回はアサーションが呼び出されたことを確認します。 非同期のコードをテストにおいて、コールバック中のアサーションが実際に呼ばれたことを確認する際にしばしば便利です。
例えば状態を取り扱ういくつかの関数があったとしましょう。 prepareState
は状態オブジェクトとともにコールバックを呼び出し、validateState
はその状態オブジェクトを確認し、 waitOnState
はprepareState
のコールバックが完了するまで待つpromiseを返します。 以下のコードでテストできます:
est('prepareState prepares a valid state', () => {
expect.hasAssertions();
prepareState(state => {
expect(validateState(state)).toBeTruthy();
});
return waitOnState();
});
expect.hasAssertions()
は prepareState
のコールバックが実際に呼ばれたことを確認します。
expect.objectContaining(object)
expect.objectContaining(object)
は期待されたプロパティに再帰的に一致する、いかなる受け取ったオブジェクトにも一致します。 つまり期待されるオブジェクトは受け取ったオブジェクトの 一部分 であるということです。 したがって受け取ったオブジェクトが期待されるオブジェクトに含まれないプロパティを含んでいても一致します。
期待されるオブジェクトのプロパティにリテラル値を設定する代わりに、expect.anything()
などのマッチャを使用することができます。
例えば、onPress
関数がEvent
オブジェクトと共に呼ばれ、eventが event.x
とevent.y
プロパティを持っていることだけ確認できれば良いと考えましょう。 以下のようにできます:
test('onPress gets called with the right thing', () => {
const onPress = jest.fn();
simulatePresses(onPress);
expect(onPress).toBeCalledWith(
expect.objectContaining({
x: expect.any(Number),
y: expect.any(Number),
}),
);
});
expect.stringContaining(string)
jest バージョン19.0.0+で利用可能
expect.stringContaining(string)
は期待された文字列とぴったり一致する受け取った文字列と一致します。
expect.stringMatching(regexp)
expect.stringMatching(regexp)
は期待する正規表現に合致する受け取った文字列と一致します。
以下のケースでリテラル値の代わりに使用できます:
toEqual
またはtoBeCalledWith
の中arrayContaining
の要素とマッチさせる場合objectContaining
またはtoMatchObject
のプロパティとマッチさせる場合
この例ではexpect.arrayContaining
内のexpect.stringMatching
によって、複数の非対称なマッチャをネストする方法も示します。
describe('stringMatching in arrayContaining', () => {
const expected = [
expect.stringMatching(/^Alic/),
expect.stringMatching(/^[BR]ob/),
];
it('matches even if received contains additional elements', () => {
expect(['Alicia', 'Roberto', 'Evelina']).toEqual(
expect.arrayContaining(expected),
);
});
it('does not match if received does not contain expected elements', () => {
expect(['Roberto', 'Evelina']).not.toEqual(
expect.arrayContaining(expected),
);
});
});
expect.addSnapshotSerializer(serializer)
expect.addSnapshotSerializer
を使用して、アプリケーション独自のデータ構造をフォーマットするモジュールを追加することができます。
個々のテストファイルにおいては、JavaScriptに組み込みの型やReactの要素のデフォルトのスナップショットのシリアライザよりもsnapshotSerializers
設定で追加されたモジュールが優先され、それらの全てのモジュールより(このAPIで) 追加されたモジュールは優先されます。 最後に追加されたモジュールが最初に確認されるモジュールになります。
import serializer from 'my-serializer-module';
expect.addSnapshotSerializer(serializer);
// affects expect(value).toMatchSnapshot() assertions in the test file
snapshotSerializers
設定で追加するのではなく、個々のテストファイルでスナップショットのシリアライザをつい以下する場合は:
- 依存関係を暗黙的でなく明示的なものにしてください。
- create-react-appが利用できなくなるような設定は避けてください。
詳細については configuring Jest を参照してください。
.not
If you know how to test something, .not
lets you test its opposite. For example, this code tests that the best La Croix flavor is not coconut:
test('the best flavor is not coconut', () => {
expect(bestLaCroixFlavor()).not.toBe('coconut');
});
.resolves
jest バージョン20.0.0+で利用可能
Use resolves
to unwrap the value of a fulfilled promise so any other matcher can be chained. If the promise is rejected the assertion fails.
例えば、以下のコードでは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
jest バージョン20.0.0+で利用可能
Use .rejects
to unwrap the reason of a rejected promise so any other matcher can be chained. If the promise is fulfilled the assertion fails.
例えば、このコードは 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');
});
.toBe(value)
Use .toBe
to compare primitive values or to check referential identity of object instances.
例えば以下のコードでは 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');
});
});
Don't use .toBe
with floating-point numbers. 例えば、JavaScriptでは数値の丸めによって0.2 + 0.1
と 0.3
は厳密には等価ではありません。 浮動小数点がある場合は、代わりに.toBeCloseTo
を使用してください。
Although the .toBe
matcher checks referential identity, it reports a deep comparison of values if the assertion fails. If differences between properties do not help you to understand why a test fails, especially if the report is large, then you might move the comparison into the expect
function. For example, to assert whether or not elements are the same instance:
- 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()
次の別名でも同様となります: .toBeCalled()
モック関数が呼ばれたかを確認するには.toHaveBeenCalled
を使用して下さい。
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 for 'lemon'
, but not for 'octopus'
, because 'octopus'
flavour is really weird and why would anything be octopus-flavoured? このテストスイートでテストすることができます:
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, ...)
次の別名でも同様となります: .toBeCalledWith()
モック関数が特定の引数を与えられて呼び出されたことを確認するには .toHaveBeenCalledWith
を使用して下さい。
例えば 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, ...)
次の別名でも同様となります: .lastCalledWith(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');
});
.toHaveLength(number)
オブジェクトが.length
プロパティを持ち、特定の数値であるかを確認するには、.toHaveLength
を使用して下さい。
配列や文字列のサイズを確認するのに特に便利です。
expect([1, 2, 3]).toHaveLength(3);
expect('abc').toHaveLength(3);
expect('').not.toHaveLength(5);
.toHaveProperty(keyPath, value)
オブジェクトの指定された参照keyPath
のプロパティが存在するかを確認するには、.toHaveProperty
を使用して下さい。 オブジェクト内で深くネストされたプロパティをチェックするには、 深い階層を参照するために、 ドット表記や keyPath を含む配列を使用することができます。
必要に応じて、 value
を指定して、対象とするオブジェクトのkeyPath
の現在の値と等しいかを確認することができます。 このマッチャは(toEqual()
のように) 'deep equality' を利用して再帰的に全てのフィールドの等価性を確認します。
次に示す例ではネストされたプロパティを含む houseForSale
オブジェクトを含んでいます。 ここでは、オブジェクト内の様々なプロパティの存在と値をチェックするために、toHaveProperty
を利用しています。
// Object containing house features to be tested
const houseForSale = {
bath: true,
bedrooms: 4,
kitchen: {
amenities: ['oven', 'stove', 'washer'],
area: 20,
wallColor: 'white',
},
};
test('this house has my desired features', () => {
// Example Referencing
expect(houseForSale).toHaveProperty('bath');
expect(houseForSale).toHaveProperty('bedrooms', 4);
expect(houseForSale).not.toHaveProperty('pool');
// Deep referencing using dot notation
expect(houseForSale).toHaveProperty('kitchen.area', 20);
expect(houseForSale).toHaveProperty('kitchen.amenities', [
'oven',
'stove',
'washer',
]);
expect(houseForSale).not.toHaveProperty('kitchen.open');
// Deep referencing using an array containing the keyPath
expect(houseForSale).toHaveProperty(['kitchen', 'area'], 20);
expect(houseForSale).toHaveProperty(
['kitchen', 'amenities'],
['oven', 'stove', 'washer'],
);
expect(houseForSale).toHaveProperty(['kitchen', 'amenities', 0], 'oven');
expect(houseForSale).not.toHaveProperty(['kitchen', 'open']);
});
.toBeCloseTo(number, numDigits)
Using exact equality with floating point numbers is a bad idea. Rounding means that intuitive things fail. For example, this test fails:
test('adding works sanely with decimals', () => {
expect(0.2 + 0.1).toBe(0.3); // Fails!
});
It fails because in JavaScript, 0.2 + 0.1
is actually 0.30000000000000004
. Sorry.
代わりに .toBeCloseTo
を使用して下さい。 numDigits
で小数点以下の何位まで確認するのかを制御できます。 例えば、 0.2 + 0.1
が 0.3
に等しいことを小数点5位の精度で確認したい場合は、このようにテストできます:
test('adding works sanely with decimals', () => {
expect(0.2 + 0.1).toBeCloseTo(0.3, 5);
});
numDigits
のデフォルト値は2で、大抵のケースにおいて適切なデフォルト値であると証明されています。
.toBeDefined()
変数がundefinedでないことを確認するには .toBeDefined
を使用します。 For example, if you want to check that a function fetchNewFlavorIdea()
returns something, you can write:
test('there is a new flavor idea', () => {
expect(fetchNewFlavorIdea()).toBeDefined();
});
expect(fetchNewFlavorIdea()).not.toBe(undefined)
とも書くことができますが、undefined
を直接コード内で参照するのは避けたほうが実務上良いでしょう。
.toBeFalsy()
Use .toBeFalsy
when you don't care what a value is and you want to ensure a value is false in a boolean context. For example, let's say you have some application code that looks like:
drinkSomeLaCroix();
if (!getErrors()) {
drinkMoreLaCroix();
}
getErrors
がどんなものを返すかは特に気にしないでしょう - false
、null
、あるいは 0
を返すかもしれませんが、それでもコードは動作します。 だからラクロワ飲料を飲んだ後でエラーが無いことをテストしたければ、このように書くことができます:
test('drinking La Croix does not lead to errors', () => {
drinkSomeLaCroix();
expect(getErrors()).toBeFalsy();
});
In JavaScript, there are six falsy values: false
, 0
, ''
, null
, undefined
, and NaN
. Everything else is truthy.
.toBeGreaterThan(number)
To compare floating point numbers, you can use toBeGreaterThan
. For example, if you want to test that ouncesPerCan()
returns a value of more than 10 ounces, write:
test('ounces per can is more than 10', () => {
expect(ouncesPerCan()).toBeGreaterThan(10);
});
.toBeGreaterThanOrEqual(number)
To compare floating point numbers, you can use toBeGreaterThanOrEqual
. For example, if you want to test that ouncesPerCan()
returns a value of at least 12 ounces, write:
test('ounces per can is at least 12', () => {
expect(ouncesPerCan()).toBeGreaterThanOrEqual(12);
});
.toBeLessThan(number)
To compare floating point numbers, you can use toBeLessThan
. For example, if you want to test that ouncesPerCan()
returns a value of less than 20 ounces, write:
test('ounces per can is less than 20', () => {
expect(ouncesPerCan()).toBeLessThan(20);
});
.toBeLessThanOrEqual(number)
To compare floating point numbers, you can use toBeLessThanOrEqual
. For example, if you want to test that ouncesPerCan()
returns a value of at most 12 ounces, write:
test('ounces per can is at least 12', () => {
expect(ouncesPerCan()).toBeGreaterThanOrEqual(12);
});
.toBeInstanceOf(Class)
Use .toBeInstanceOf(Class)
to check that an object is an instance of a class. This matcher uses instanceof
underneath.
class A {}
expect(new A()).toBeInstanceOf(A);
expect(() => {}).toBeInstanceOf(Function);
expect(new A()).toBeInstanceOf(Function); // throws
.toBeNull()
.toBeNull()
is the same as .toBe(null)
but the error messages are a bit nicer. So use .toBeNull()
when you want to check that something is null.
function bloop() {
return null;
}
test('bloop returns null', () => {
expect(bloop()).toBeNull();
});
.toBeTruthy()
Use .toBeTruthy
when you don't care what a value is and you want to ensure a value is true in a boolean context. For example, let's say you have some application code that looks like:
drinkSomeLaCroix();
if (thirstInfo()) {
drinkMoreLaCroix();
}
thirstInfo
がどんなものを返すかは特に気にしないでしょう - true
もしくは複雑な値を返すかもしれませんが、それでもコードは動作します。 So if you want to test that thirstInfo
will be truthy after drinking some La Croix, you could write:
test('drinking La Croix leads to having thirst info', () => {
drinkSomeLaCroix();
expect(thirstInfo()).toBeTruthy();
});
In JavaScript, there are six falsy values: false
, 0
, ''
, null
, undefined
, and NaN
. Everything else is truthy.
.toBeUndefined()
変数がundefinedであることを確認するには .toBeUndefined
を使用します。 例えば、 関数bestDrinkForFlavor(flavor)
が'octopus'
味が与えられた時にundefined
を返すことを確認したいとしましょう。タコ味の美味しい飲み物なんてありませんから:
test('the best drink for octopus flavor is undefined', () => {
expect(bestDrinkForFlavor('octopus')).toBeUndefined();
});
expect(bestDrinkForFlavor('octopus')).toBe(undefined)
とも書くことができますが、undefined
を直接コード内で参照するのは避けたほうが実務上良いでしょう。
.toBeNaN()
Use .toBeNaN
when checking a value is NaN
.
test('passes when value is NaN', () => {
expect(NaN).toBeNaN();
expect(1).not.toBeNaN();
});
.toContain(item)
アイテムが配列内にあることを確認したい場合は、.toContain
を使用します。 配列内のアイテムをテストするために、 このマッチャは===
を使用して厳密な等価性のチェックを行います。 .toContain
は、ある文字列が別の文字列の部分文字列であるかをチェックすることもできます。
例えば getAllFlavors()
が風味の配列を返し、lime
がその中にある事を確認したいなら、このように書くことができます:
test('the flavor list contains lime', () => {
expect(getAllFlavors()).toContain('lime');
});
.toContainEqual(item)
特定の構造と値を持つ要素が配列に含まれていることをチェックしたい場合は.toContainEqual
を使用して下さい。 配列中のアイテムをテストするために、このマッチャはオブジェクトIDではなく、再帰的に全てのフィールドの等価性を確認します。
describe('my beverage', () => {
test('is delicious and not sour', () => {
const myBeverage = {delicious: true, sour: false};
expect(myBeverages()).toContainEqual(myBeverage);
});
});
.toEqual(value)
Use .toEqual
to compare recursively all properties of object instances (also known as "deep" equality).
For example, .toEqual
and .toBe
behave differently in this test suite, so all the tests pass:
const can1 = {
flavor: 'grapefruit',
ounces: 12,
};
const can2 = {
flavor: 'grapefruit',
ounces: 12,
};
describe('the La Croix cans on my desk', () => {
test('have all the same properties', () => {
expect(can1).toEqual(can2);
});
test('are not the exact same can', () => {
expect(can1).not.toBe(can2);
});
});
注意:
.toEqual
は2つのエラーに deep equalityを実施しません。 エラーオブジェクトのmessage
プロパティのみを等価性の比較対象とします。 エラーに対するテストは.toThrow
マッチャの使用をお勧めします。
If differences between properties do not help you to understand why a test fails, especially if the report is large, then you might move the comparison into the expect
function. For example, use equals
method of Buffer
class to assert whether or not buffers contain the same content:
- rewrite
expect(received).toEqual(expected)
asexpect(received.equals(expected)).toBe(true)
- rewrite
expect(received).not.toEqual(expected)
asexpect(received.equals(expected)).toBe(false)
.toMatch(regexpOrString)
文字列が正規表現と一致することを確認するには.toMatch
を使用して下さい。
例えば、essayOnTheBestFlavor()
がどのようなものか正確には分からないけれども本当に長い文字列を返すこと、そして grapefruit
という文字列がその中のどこかに含まれるべきであるということを知っているとしましょう。 以下のコードでテストできます:
describe('an essay on the best flavor', () => {
test('mentions grapefruit', () => {
expect(essayOnTheBestFlavor()).toMatch(/grapefruit/);
expect(essayOnTheBestFlavor()).toMatch(new RegExp('grapefruit'));
});
});
このマッチャは正規表現と照合する対象に文字列も取ることができます:
describe('grapefruits are healthy', () => {
test('grapefruits are a fruit', () => {
expect('grapefruits').toMatch('fruit');
});
});
.toMatchObject(object)
JavaScript オブジェクトが、あるオブジェクトのプロパティのサブセットに一致することを確認するには.ToMatchObject
を使用して下さい。 期待されるオブジェクトに含まれないプロパティを含む引数のオブジェクトについても一致します。
オブジェクトの配列を渡すこともでき、その場合はメソッドは期待する配列の対応するオブジェクトと引数の配列の各オブジェクトが( 上述のtoMatchObject
と同じ意味で) 一致する場合のみ真を返します。 このAPIは引数の配列が余分な要素を持つことを受容する arrayContaining
とは反対に、2つの配列がその数で一致することを確認するのに便利です。
プロパティは値またはマッチャでマッチすることができます。
const houseForSale = {
bath: true,
bedrooms: 4,
kitchen: {
amenities: ['oven', 'stove', 'washer'],
area: 20,
wallColor: 'white',
},
};
const desiredHouse = {
bath: true,
kitchen: {
amenities: ['oven', 'stove', 'washer'],
wallColor: expect.stringMatching(/white|yellow/),
},
};
test('the house has my desired features', () => {
expect(houseForSale).toMatchObject(desiredHouse);
});
describe('toMatchObject applied to arrays', () => {
test('the number of elements must match exactly', () => {
expect([{foo: 'bar'}, {baz: 1}]).toMatchObject([{foo: 'bar'}, {baz: 1}]);
});
// .arrayContaining "matches a received array which contains elements that
// are *not* in the expected array"
test('.toMatchObject does not allow extra elements', () => {
expect([{foo: 'bar'}, {baz: 1}]).toMatchObject([{foo: 'bar'}]);
});
test('.toMatchObject is called for each elements, so extra object properties are okay', () => {
expect([{foo: 'bar'}, {baz: 1, extra: 'quux'}]).toMatchObject([
{foo: 'bar'},
{baz: 1},
]);
});
});
.toMatchSnapshot(optionalString)
This ensures that a value matches the most recent snapshot. Check out the Snapshot Testing guide for more information.
You can also specify an optional snapshot name. Otherwise, the name is inferred from the test.
.toThrow(error)
次の別名でも同様となります: .toThrowError(error)
関数が呼ばれた際にエラーを投げることを確認するには.toThrow
を使用して下さい。 例えば、タコ味なんて気持ち悪すぎて飲めないのでdrinkFlavor('octopus')
が例外を投げることをテストしたい場合、次のように書くことができます:
test('throws on octopus', () => {
expect(() => {
drinkFlavor('octopus');
}).toThrow();
});
注意: 関数の中のコードはラップしてください。そうしなければエラーが補足されず、アサーションは失敗します。
特定のエラーがスローされることをテストしたい場合は、toThrow
に引数を与えることができます。 The argument can be a string that should be contained in the error message, a class for the error, or a regex that should match the error message. 例えば、drinkFlavor
はこのようにコーディングされたとしましょう:
function drinkFlavor(flavor) {
if (flavor == 'octopus') {
throw new DisgustingFlavorError('yuck, octopus flavor');
}
// Do some other stuff
}
いくつかの方法でこのエラーが投げられることをテストできます:
test('throws on octopus', () => {
function drinkOctopus() {
drinkFlavor('octopus');
}
// Test that the error message says "yuck" somewhere: these are equivalent
expect(drinkOctopus).toThrowError(/yuck/);
expect(drinkOctopus).toThrowError('yuck');
// Test the exact error message
expect(drinkOctopus).toThrowError(/^yuck, octopus flavor$/);
// Test that we get a DisgustingFlavorError
expect(drinkOctopus).toThrowError(DisgustingFlavorError);
});
.toThrowErrorMatchingSnapshot()
関数が呼ばれた際に直近のスナップショットと一致するエラーを投げることを確認するには、 .toThrowErrorMatchingSnapshot
を使用して下さい。 例えば、 風味が'octopus'
ならば必ずエラーを投げるdrinkFlavor
関数があり、次のようなコードだったとします:
function drinkFlavor(flavor) {
if (flavor == 'octopus') {
throw new DisgustingFlavorError('yuck, octopus flavor');
}
// Do some other stuff
}
この関数のテストはこのようになります:
test('throws on octopus', () => {
function drinkOctopus() {
drinkFlavor('octopus');
}
expect(drinkOctopus).toThrowErrorMatchingSnapshot();
});
そして次のようなスナップショットを生成します:
exports[`drinking flavors throws on octopus 1`] = `"yuck, octopus flavor"`;
スナップショットテストについての詳細はReact Tree Snapshot Testingを確認して下さい。