Expect
Когда вы пишете тесты, вам, как правило, необходимо проверять, что значения соответствуют определенным условиям. expect
предоставляет вам доступ к ряду «проверок» (matchers), которые позволяют сопоставить результаты с ожиданиями.
Методы #
Справка #
expect(value)
#
Функция expect
используется каждый раз, когда вы хотите проверить значение. Однако, вам редко придется вызывать expect
саму по себе. Вместо этого вы будете использовать expect
вместе с функцией-проверкой для утверждения чего-либо о значении.
Это легче понять на примере. Скажем, у вас есть метод bestLaCroixFlavor()
, который должен возвращать строку «грейпфрут»
. Вот как можно это протестировать:
test('лучший вкус это грейпфрут', () => { expect(bestLaCroixFlavor()).toBe('грейпфрут'); });
В данном случае для проверки значения используется функция toBe
. Существует множество подобных функций, которые помогут вам тестировать различные вещи. Их список приведён ниже.
Аргументом для функции expect
должно быть значение, которое возвращает ваш код, а в функцию проверки необходимо передавать ожидаемое верное значение. Если их перепутать местами, то тесты будут продолжать работать, а вот сообщения об ошибках в тестах будут выглядеть странно.
expect.extend(matchers)
#
expect.extend
используется для добавления новых проверок в Jest. Предположим, что вы тестируете библиотеку для работы с числами и вам довольно часто необходимо проверять, что числа делятся на другие числа без остатка. Тогда вы могли бы написать функцию toBeDivisibleBy
, которая проверяет это:
expect.extend({ toBeDivisibleBy(received, argument) { const pass = (received % argument == 0); if (pass) { return { message: () => ( `ожидалось что ${received} не делится на ${argument}` ), pass: true, }; } else { return { message: () => (`ожидалось что ${received} делится на ${argument}`), pass: false, }; } }, });
Функции-проверки должны возвращать объект с двумя ключами. Ключ pass
указывает было ли совпадение успешным или нет, а message
представляет собой функцию без аргументов, которая возвращает сообщение об ошибке в случае проваленого теста. То есть, если pass
имеет значение false, функция message
должна возвращать сообщение об ошибке в случае если expect(x).yourMatcher()
не выполняется. Когда же pass
имеет значение true, функция message
должна возвращать сообщение об ошибке в случае, если не выполняется expect(x).not.yourMatcher()
.
По ссылке this
внутри пользовательской проверки можно получить доступ к следующим вспомогательным методам:
this.isNot
#
Значение типа boolean, сигнализирующее о том, что функция была вызвана с модификатором отрицания .not
, позволяющим инвертировать утверждение.
this.equals(a, b)
#
Функция для проверки двух объектов на равенство (в т. ч. вложенных свойств). Возвращает значение типа boolean
.
this.utils
#
Существует целый ряд полезных инструментов доступных через this.utils
и в основном состоящий из функций экспортируемых из jest-matcher-utils
.
Наиболее полезными из них являются matcherHint
, printExpected
и printReceived
для форматирования сообщений об ошибках. Например, взгляните как это реализовано для функции toBe
:
const diff = require('jest-diff'); expect.extend({ toBe(received, expected) { const pass = received === expected; const message = pass ? () => this.utils.matcherHint('.not.toBe') + '\n\n' + `Expected value to not be (using ===):\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 ===):\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 ===): "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(mock); 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)
проверяет, что во время выполнения теста было вызвано определённое число проверок. Это обычно полезно для тестирования асинхронного кода, чтобы удостовериться, что проверки действительно были вызваны в функциях обратного вызова.
Скажем, у нас есть функция doAsync
, которая получает на вход две функции обратного вызова callback1
и callback2
. Обе этих функции будут вызваны асинхронно в неизвестном заранее порядке. Это можно протестировать так:
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()
проверяет, что во время выполнения теста была вызвана хотя бы одна проверка. Это обычно полезно для тестирования асинхронного кода, чтобы удостовериться, что проверки действительно были вызваны в функциях обратного вызова.
Предположим, что у нас есть несколько функций, которые работают с неким состоянием. prepareState
запускает функцию обратного вызова с объектом состояния, validateState
выполняет над этим объектом некую операцию, а waitOnState
возвращает Promise, который ожидает, пока все фунцкии обратного вызова внутри prepareState
не будут выполнены. Это можно протестировать так:
test('prepareState prepares a valid state', () => { expect.hasAssertions(); prepareState(state => { expect(validateState(state)).toBeTruthy(); }); return waitOnState(); });
Код expect.hasAssertions()
проверяет, что функция обратного вызова в prepareState
была вызвана.
expect.objectContaining(object)
#
expect.objectContaining(object)
проверяет (рекурсивно), что данный объект имеет те или иные свойства. Иными словами, что тестовый объект является подмножеством данного. Отсюда в том числе следует, что этот объект может содержать свойста, которых нет в тестовом.
Instead of literal property values in the expected object, you can use matchers, expect.anything()
, and so on.
Предположим, мы ожидаем, что функция onPress
будет вызвана с объектом 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.stringMatching
находится внутри expect.arrayContaining
.
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
для добавления модуля, который поддерживает форматирование структур данных, специфичных для вашего приложения.
Для каждого файла, содержащего тесты, добавленный таким образом модуль будет предшествовать всем модулям, объявленным в параметре конфигурации snapshotSerializers
. Те, в свою очередь, предшествуют сериализаторам снимков для встроенных типов JavaScript и элементов React, включённым в Jest по-умолчанию. Последний добавленный модуль будет протестирован первым.
import serializer from 'my-serializer-module'; expect.addSnapshotSerializer(serializer); // влияет на поведение проверки expect(value).toMatchSnapshot() в файле с тестами
Если вы добавляете сериализатор снимков в файл с тестами вместо того, чтобы объявить его в параметре конфигурации snapshotSerializers
, то:
- Вы делаете зависимость явной.
- Вы избегаете ограничений конфигурации, которые могут помешать вам использовать create-react-app.
Дополнительную информацию можно найти на странице [настройка Jest](/jest/docs/configuration. html#snapshotserializers-array-string).
.not
#
Если вы знаете как можно проверить некое утверждение, то .not
позволяет вам проверить обратное ему утверждение. Например, следующий код проверяет, что лучший вкус газировки La Croix не является кокосовым:
test('the best flavor is not coconut', () => { expect(bestLaCroixFlavor()).not.toBe('coconut'); });
.resolves
#
доступно в версиях Jest 20.0.0+ #
Используйте resolves
для возврата значения из объекта типа Promise. К возвращённому таким образом значению можно применять другие функции-проверки. Данный метод работает только с объектами Promise в состоянии «выполнено». Если объект Promise находится в состоянии «отклонено», то проверка не выполняется.
Например, следующий код проверяет, что Promise выполняется и результатом будет 'lemon'
:
test('resolves to lemon', () => { // не забудьте добавить оператор return return expect(Promise.resolve('lemon')).resolves.toBe('lemon'); });
Кроме того, вы можете использовать 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+ #
Используйте .rejects
для возврата значения из объекта типа Promise. К возвращённому таким образом значению можно применять другие функции-проверки. Данный метод работает только с объектами Promise в состоянии «отклонено». Если объект Promise находится в состоянии «выполнено», то проверка не выполняется.
Например, следующий код проверяет, что Promise отклонён с определённым сообщением об ошибке:
test('fetchData() rejects to be error', () => { // не забудьте добавить оператор return return expect(Promise.reject('octopus')).rejects.toBeDefined(); });
Кроме того, вы можете использовать async/await
в комбинации с .rejects
. Следующий код проверяет, что сообщение об ошибке содержит 'octopus':
test('fetchData() rejects to be error', async () => { const drinkOctopus = new Promise(() => { throw new DisgustingFlavorError('yuck, octopus flavor'); }); await expect(drinkOctopus).rejects.toMatch('octopus'); });
.toBe(value)
#
toBe
просто проверяет, что значение соответствует ожидаемому. Эта функция использует строгую проверку на равенство ===
.
For example, this code will validate some properties of the can
object:
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
если вам необходимо сравнивать числа с плавающей точкой.
.toHaveBeenCalled()
#
Другое имя функции: .toBeCalled()
Используйте .toHaveBeenCalled
, чтобы убедиться, что функция-заглушка была вызвана.
Предположим, что у вас есть функция drinkAll(drink, flavor)
, которая принимает в качестве параметра функцию drink
и вызывает её для всех напитков в вашей системе. Вам может потребоваться протестировать, что drink
была вызвана для напитка 'lemon'
, но никак не для напитка 'octopus'
. Было бы весьма странным иметь напиток со вкусом осьминога, не правда ли? Это можно сделать при помощи следующего теста:
describe('drinkAll', () => { test('drinks something lemon-flavored', () => { const drink = jest.fn(); drinkAll(drink, 'lemon'); expect(drink).toHaveBeenCalled(); }); test('does not drink something octopus-flavored', () => { const drink = jest.fn(); drinkAll(drink, 'octopus'); expect(drink).not.toHaveBeenCalled(); }); });
.toHaveBeenCalledTimes(number)
#
Используйте .toHaveBeenCalledTimes
, чтобы убедиться, что функция-заглушка была вызвана строго определённое число раз.
Например, у вас может быть функция drinkEach(drink, Array<flavor>)
, которая принимает в качестве параметра функцию drink
и вызывает её для каждого элемента массива напитков. Тогда вам может потребоваться проверить, что функция drink была вызвана определённое число раз. Это можно сделать при помощи следующего теста:
test('drinkEach drinks each drink', () => { const drink = jest.fn(); drinkEach(drink, ['lemon', 'octopus']); expect(drink).toHaveBeenCalledTimes(2); });
.toHaveBeenCalledWith(arg1, arg2, ...)
#
Also under the alias: .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
, чтобы убедиться, что в последний раз функция-заглушка была вызвана с определённым набором аргументов. Например, ваша функция applyToAllFlavors(f)
вызывает функцию drink
для набора напитков. Вы хотите убедиться, что последним был вызван напиток 'mango'
. Вы можете написать:
test('applying to all flavors does mango last', () => { const drink = jest.fn(); applyToAllFlavors(drink); expect(drink).toHaveBeenLastCalledWith('mango'); });
.toBeCloseTo(number, numDigits)
#
Использовать оператор равенства для сравнения чисел с плавающей точкой — это плохая идея. Когда работает округление, перестают работать очевидные вещи. Нпример, этот тест не будет пройден:
test('adding works sanely with simple decimals', () => { expect(0.2 + 0.1).toBe(0.3); // Неверно! });
А неверно это потому, что в JavaScript 0.2 + 0.1
равно 0.30000000000000004
. Уж извините.
Вместо этого используйте .toBeCloseTo
. Параметр numDigits
определяет сколько разрядов после запятой необходимо учитывать. Например, если вам нужно убедиться, что 0.2 + 0.1
равно 0.3
с точностью до пяти знаков после запятой, можно написать следующее:
test('adding works sanely with simple decimals', () => { expect(0.2 + 0.1).toBeCloseTo(0.3, 5); });
По-умолчанию numDigits
равен 2, что в большинстве случаев достаточно.
.toBeDefined()
#
Используйте .toBeDefined
для проверки того, что переменная определена. Например, если вы просто хотите проверить, что функция fetchNewFlavorIdea()
возвращает что-то, вы можете написать:
test('there is a new flavor idea', () => { expect(fetchNewFlavorIdea()).toBeDefined(); });
Конечно, можно было бы написать expect(fetchNewFlavorIdea()).not.toBe(undefined)
, но лучше избегать использования undefined
непосредственно в вашем коде.
.toBeFalsy()
#
Используйте .toBeFalsy
когда вам всего лишь необходимо проверить, что значение эквивалентно ложному. Предположим, что у вас есть следующий код:
drinkSomeLaCroix(); if (!getErrors()) { drinkMoreLaCroix(); }
Вам не так уж важно что возвращает getErrors
. Она может вернуть false
, null
или ``, однако ваш код будет корректно работать. И если вы хотите протестировать, что после употребления газировки La Croix не произошло никаких ошибок, то можно написать:
test('drinking La Croix does not lead to errors', () => { drinkSomeLaCroix(); expect(getErrors()).toBeFalsy(); });
В JavaScript существует всего шесть значений, эквивалетных ложному: false
, `,
'',
null,
undefinedи
NaN`. Всё остальное эквивалентно истине.
.toBeGreaterThan(number)
#
Для сравнения чисел с плавающей точкой можно использовать toBeGreaterThan
. Например, если вы хотите проверить, что ouncesPerCan()
возвращает значение, которое больше чем 10 унций, пишите:
test('ounces per can is more than 10', () => { expect(ouncesPerCan()).toBeGreaterThan(10); });
.toBeGreaterThanOrEqual(number)
#
Для сравнения чисел с плавающей точкой можно использовать toBeGreaterThanOrEqual
. Например, если вы хотите проверить, что ouncesPerCan()
возвращает значение, которое не меньше чем 12 унций, пишите:
test('ounces per can is at least 12', () => { expect(ouncesPerCan()).toBeGreaterThanOrEqual(12); });
.toBeLessThan(number)
#
Для сравнения чисел с плавающей точкой можно использовать toBeLessThan
. Например, если вы хотите проверить, что ouncesPerCan()
возвращает значение, которое меньше чем 20 унций, пишите:
test('ounces per can is less than 20', () => { expect(ouncesPerCan()).toBeLessThan(20); });
.toBeLessThanOrEqual(number)
#
Для сравнения чисел с плавающей точкой можно использовать toBeLessThanOrEqual
. Например, если вы хотите проверить, что ouncesPerCan()
возвращает значение, которое не больше чем 12 унций, пишите:
test('ounces per can is at most 12', () => { expect(ouncesPerCan()).toBeLessThanOrEqual(12); });
.toBeInstanceOf(Class)
#
Используйте .toBeInstanceOf(Class)
, чтобы проверить, что данный объект является экземпляром того или иного класса. Эта функция использует оператор instanceof
.
class A {} expect(new A()).toBeInstanceOf(A); expect(() => {}).toBeInstanceOf(Function); expect(new A()).toBeInstanceOf(Function); // throws
.toBeNull()
#
.toBeNull()
ведёт себя точно так же, как .toBe(null)
, просто её сообщения об ошибках выглядят получше. Так что, если вам нужно проверить, что что-то является null, то используйте .toBeNull()
.
function bloop() { return null; } test('bloop returns null', () => { expect(bloop()).toBeNull(); });
.toBeTruthy()
#
Используйте .toBeTruthy
когда вам всего лишь необходимо проверить, что значение эквивалентно истинному. Предположим, что у вас есть следующий код:
drinkSomeLaCroix(); if (thirstInfo()) { drinkMoreLaCroix(); }
Вам не так уж важно, что возвращает thirstInfo
. Она может вернуть true
или целый объект, однако ваш код будет корректно работать. Так что если вы просто хотите проверить, что thirstInfo
вернёт значение эквивалетное истинному после употребления газировки La Croix, можно написать:
test('drinking La Croix leads to having thirst info', () => { drinkSomeLaCroix(); expect(thirstInfo()).toBeTruthy(); });
В JavaScript существует всего шесть значений, эквивалетных ложному: false
, `,
'',
null,
undefinedи
NaN`. Всё остальное эквивалентно истине.
.toBeUndefined()
#
Используйте .toBeUndefined
, чтобы проверить, что переменная не определена. Например, вы хотите проверить, что функция bestDrinkForFlavor(flavor)
возвращает undefined
для вкуса 'octopus'
. Просто потому, что напитков со вкусом осьминога не существует:
test('the best drink for octopus flavor is undefined', () => { expect(bestDrinkForFlavor('octopus')).toBeUndefined(); });
Конечно, можно было бы написать expect(bestDrinkForFlavor('octopus')).toBe(undefined)
, но лучше избегать использования undefined
непосредственно в вашем коде.
.toContain(item)
#
Используйте .toContain
если вы хотите убедиться, что тот или иной элемент находится в списке. Эта функция использует оператор строгого равенства ===
.
Например, если getAllFlavors()
возвращает список вкусов, и вы хотите быть уверены, что в нём присутствует lime
, то вы можете написать:
test('the flavor list contains lime', () => { expect(getAllFlavors()).toContain('lime'); });
.toContainEqual(item)
#
Используйте .toContainEqual
если вы хотите убедиться, что тот или иной элемент находится в списке. Вместо проверки объектов на идентичность, эта функция рекурсивно сравнивает все поля в объектах.
describe('my beverage', () => { test('is delicious and not sour', () => { const myBeverage = {delicious: true, sour: false}; expect(myBeverages()).toContainEqual(myBeverage); }); });
.toEqual(value)
#
Используйте .toEqual
, когда вы хотите проверить, что два объекта имеют одинаковое значение. Вместо проверки объектов на идентичность, эта функция рекурсивно сравнивает все поля в объектах. Эта процедура ещё называется «проверка на глубокое равенство». Например toEqual
и toBe
ведут себя по-разному в этом наборе, и, таким образом, все тесты успешно выполняются:
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
не сможет выполнить проверку на глубокое равенство для объектов типа Error. В этих объектах проверяется на равенство только свойствоmessage
. Поэтому для тестирования исключений рекомендуется использовать функцию.toThrow
.
.toHaveLength(number)
#
Используйте .toHaveLength
для проверки того, что объект имеет свойство .length
, и оно имеет определённое значение.
Это особенно полезно для проверки размера массивов или строк.
expect([1, 2, 3]).toHaveLength(3); expect('abc').toHaveLength(3); expect('').not.toHaveLength(5);
.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)
#
Используйте .toMatchObject
для проверки того, что некий объект содержит подмножество свойств текущего объекта. It will match received objects with properties that are not in the expected object.
You can also pass an array of objects, in which case the method will return true only if each object in the received array matches (in the toMatchObject
sense described above) the corresponding object in the expected array. This is useful if you want to check that two arrays match in their number of elements, as opposed to arrayContaining
, which allows for extra elements in the received array.
You can match properties against values or against matchers.
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 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 } ]); }); });
.toHaveProperty(keyPath, value)
#
Используйте .toHaveProperty
для проверки того, что в данном объекте есть свойство keyPath
. Для проверки глубоко вложенных свойств используйте точечную нотацию.
Кроме того, можно указать параметр value
для проверки того, что значение свойства keyPath
в объекте соответствует заданному. Эта функция использует «глубокое равенство» (как и toEqual()
) и проверяет равенство полей рекурсивно.
В следующем примере содержится объект 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', () => { // Simple 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'); });
.toMatchSnapshot(optionalString)
#
Проверяет, что значение соответствует наиболее свежему снимку. За дополнительной информацией обращайтесь к разделу Тестирование при помощи снимков.
В функцию можно передать имя снимка. В противном случае имя определяется из теста.
Примечание: тестирование при помощи снимков, как правило, применяется к компонентам React. Тем не менее, любое сериализуемое значение может быть использовано в качестве снимка.
.toThrow(error)
#
Другое имя функции: .toThrowError()
Используйте .toThrow
для проверки, что функция бросает исключение при вызове. Например, если бы мы хотели проверить, что функция drinkFlavor('octopus')
кидает исключение, потому что газировка со вкусом осьминога слишком отвратительна для питья, мы могли бы написать:
test('throws on octopus', () => { expect(() => { drinkFlavor('octopus'); }).toThrow(); });
Если вы хотите проверить, что было выброшено то или иное исключение, то можно передать аргумент в toThrow
. Этим аргументом может быть строка с сообщением об ошибке, класс исключения или регулярное выражение. Пусть в drinkFlavor
написано следующее:
function drinkFlavor(flavor) { if (flavor == 'octopus') { throw new DisgustingFlavorError('yuck, octopus flavor'); } // что угодно }
Мы можем проверить это исключение несколькими способами:
test('throws on octopus', () => { function drinkOctopus() { drinkFlavor('octopus'); } // проверяем сообщение об ошибке на полное соответствие expect(drinkOctopus).toThrowError('yuck, octopus flavor'); // проверяем, что сообщение об ошибке содержит слово "yuck" expect(drinkOctopus).toThrowError(/yuck/); // проверяем, что ошибка является DisgustingFlavorError expect(drinkOctopus).toThrowError(DisgustingFlavorError); });
.toThrowErrorMatchingSnapshot()
#
Use .toThrowErrorMatchingSnapshot
to test that a function throws an error matching the most recent snapshot when it is called. Например, у вас есть функция drinkFlavor
, которая генерирует исключение всякий раз, когда ей передают параметр 'octopus'
:
function drinkFlavor(flavor) { if (flavor == 'octopus') { throw new DisgustingFlavorError('yuck, octopus flavor'); } // что угодно }
Тест для этой функции будет выглядеть следующим образом:
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.