Expect
Когда вы пишете тесты, вам, как правило, необходимо проверять, что значения соответствуют определенным условиям. expect
предоставляет вам доступ к ряду «проверок» (matchers), которые позволяют сопоставить результаты с ожиданиями.
For additional Jest matchers maintained by the Jest Community check out jest-extended
.
Примеры TypeScript с этой страницы будут работать только в том случае, если вы явно импортируете Jest API:
Import {expect, jest, test} from '@jest/globals';
Обратитесь к Началу работы за подробностями о том, как установить Jest с TypeScript.
Справка
- Expect
- Modifiers
- 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.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
Expect
expect(value)
Функция expect
используется каждый раз, когда вы хотите проверить значение. Однако, вам редко придется вызывать expect
саму по себе. Вместо этого вы будете использовать expect
вместе с функцией-проверкой для утверждения чего-либо о значении.
Это легче понять на примере. Скажем, у вас есть метод bestLaCroixFlavor()
, который должен возвращать строку «грейпфрут»
. Вот как можно это протестировать:
test('лучший вкус это грейпфрут', () => {
expect(bestLaCroixFlavor()).toBe('грейпфрут');
});
В данном случае для проверки значения используется функция toBe
. Существует множество подобных функций, которые помогут вам тестировать различные вещи. Их список приведён ниже.
Аргументом для функции expect
должно быть значение, которое возвращает ваш код, а в функцию проверки необходимо передавать ожидаемое верное значение. Если их перепутать местами, то тесты будут продолжать работать, а вот сообщения об ошибках в тестах будут выглядеть странно.
Modifiers
.not
Если вы знаете как можно проверить некое утверждение, то .not
позволяет вам проверить обратное ему утверждение. Например, следующий код проверяет, что лучши й вкус газировки La Croix не является кокосовым:
test('the best flavor is not coconut', () => {
expect(bestLaCroixFlavor()).not.toBe('coconut');
});
.resolves
Используйте resolves
для возврата значения из объекта типа Promise. К возвращённому таким образом значению можно применять другие функции-проверки. If the promise is rejected the assertion fails.
Например, следующий код проверяет, что Promise выполняется и результатом будет 'lemon'
:
test('resolves to lemon', () => {
// не забудьте добавить оператор return
return expect(Promise.resolve('lemon')).resolves.toBe('lemon');
});
Since you are still testing promises, the test is still asynchronous. Hence, you will need to tell Jest to wait by returning the unwrapped assertion.
Кроме того, вы можете использовать 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
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.
For example, this code tests that the promise rejects with reason 'octopus'
:
test('rejects to octopus', () => {
// make sure to add a return statement
return expect(Promise.reject(new Error('octopus'))).rejects.toThrow(
'octopus',
);
});
Since you are still testing promises, the test is still asynchronous. Hence, you will need to tell Jest to wait by returning the unwrapped assertion.
Alternatively, you can use async/await
in combination with .rejects
.
test('rejects to octopus', async () => {
await expect(Promise.reject(new Error('octopus'))).rejects.toThrow('octopus');
});
Matchers
.toBe(value)
Используйте .toBe
для сравнения примитивных значений или проверки референциальной идентичности экземпляров объекта. Он вызывает Object.is
для сравнения значений, что еще лучше для тестирования, чем ===
строгий оператор равенства.
Следующий код проверяет некоторые свойства объекта 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
если вам необходимо сравнивать числа с плавающей точкой.
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()
Используйте .toHaveBeenCalledWith
, чтобы убедиться, что функция-заглушка была вызвана с определённым набором аргументов. The arguments are checked with the same algorithm that .toEqual
uses.
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)
Псевдоним метода: .toBeCalled()
Используйте .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, ...)
Псевдоним метода: .toBeCalledWith()
Используйте .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, ...)
Другое имя функции: .lastCalledWith(arg1, arg2, ...)
If you have a mock function, you can use .toHaveBeenNthCalledWith
to test what arguments it was nth called with. For example, let's say you have a drinkEach(drink, Array<flavor>)
function that applies f
to a bunch of flavors, and you want to ensure that when you call it, the first flavor it operates on is 'lemon'
and the second one is 'octopus'
. Вы можете написать:
test('applying to all flavors does mango last', () => {
const drink = jest.fn();
applyToAllFlavors(drink);
expect(drink).toHaveBeenLastCalledWith('mango');
});
.toHaveBeenNthCalledWith(nthCall, arg1, arg2, ....)
Also under the alias: .nthCalledWith(nthCall, arg1, arg2, ...)
If you have a mock function, you can use .toHaveReturned
to test that the mock function successfully returned (i.e., did not throw an error) at least one time. For example, let's say you have a mock drink
that returns true
. Вы можете написать:
test('drinkEach drinks each drink', () => {
const drink = jest.fn();
drinkEach(drink, ['lemon', 'octopus']);
expect(drink).toHaveBeenNthCalledWith(1, 'lemon');
expect(drink).toHaveBeenNthCalledWith(2, 'octopus');
});
The nth argument must be positive integer starting from 1.
.toHaveReturned()
Also under the alias: .toReturn()
If you have a mock function, you can use .toHaveReturned
to test that the mock function successfully returned (i.e., did not throw an error) at least one time. For example, let's say you have a mock drink
that returns true
. Вы можете написать:
test('drinks returns', () => {
const drink = jest.fn(() => true);
drink();
expect(drink).toHaveReturned();
});
.toHaveReturnedTimes(number)
Also under the alias: .toReturnTimes(number)
Use .toHaveReturnedTimes
to ensure that a mock function returned successfully (i.e., did not throw an error) an exact number of times. Any calls to the mock function that throw an error are not counted toward the number of times the function returned.
For example, let's say you have a mock drink
that returns true
. Вы можете написать:
test('drink returns twice', () => {
const drink = jest.fn(() => true);
drink();
drink();
expect(drink).toHaveReturnedTimes(2);
});
.toHaveReturnedWith(value)
Also under the alias: .toReturnWith(value)
Use .toHaveReturnedWith
to ensure that a mock function returned a specific value.
For example, let's say you have a mock drink
that returns the name of the beverage that was consumed. Вы можете написать:
test('drink returns La Croix', () => {
const beverage = {name: 'La Croix'};
const drink = jest.fn(beverage => beverage.name);
drink(beverage);
expect(drink).toHaveReturnedWith('La Croix');
});