Jest测试语法系列之Expect
Methods
Expect主要用于实现验证操作,Jest的Expect提供了如下的验证方法:
- expect(value)
- expect.extend(matchers)
- expect.anything()
- expect.any(constructor)
- expect.arrayContaining(array)
- expect.assertions(number)
- expect.hasAssertions()
- expect.not.arrayContaining(array)
- expect.not.objectContaining(object)
- expect.not.stringContaining(string)
- expect.not.stringMatching(string | regexp)
- expect.objectContaining(object)
- expect.stringContaining(string)
- expect.stringMatching(string | regexp)
- expect.addSnapshotSerializer(serializer)
- .not
- .resolves
- .rejects
- .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)
- .toBeCloseTo(number, numDigits)
- .toBeDefined()
- .toBeFalsy()
- .toBeGreaterThan(number)
- .toBeGreaterThanOrEqual(number)
- .toBeLessThan(number)
- .toBeLessThanOrEqual(number)
- .toBeInstanceOf(Class)
- .toBeNull()
- .toBeTruthy()
- .toBeUndefined()
- .toContain(item)
- .toContainEqual(item)
- .toEqual(value)
- .toHaveLength(number)
- .toMatch(regexpOrString)
- .toMatchObject(object)
- .toHaveProperty(keyPath, value)
- .toMatchSnapshot(propertyMatchers, snapshotName)
- .toMatchInlineSnapshot(propertyMatchers, inlineSnapshot)
- .toStrictEqual(value)
- .toThrow(error)
- .toThrowErrorMatchingSnapshot()
- .toThrowErrorMatchingInlineSnapshot()
Reference
expect(value)
每当您希望测试某个值时,就可以使用expect函数,你可能很少会调用expect本身,相反,你将使用expect和“matcher”函数来断言关于值的某些内容。为了更方便理解,这里假设您有一个方法bestLaCroixFlavor(),,它的expect期望返回结果为:
test('the best flavor is grapefruit', () => {expect(bestLaCroixFlavor()).toBe('grapefruit');
});
在上面的例子中,toBe是matcher函数,为了帮助你测试不同的内容,Jest提供了很多不同的matcher函数。expect的参数应该是代码生成的值,而匹配程序的任何参数都应该是正确的值。
expect.extend(matchers)
你可以使用expect.extend将自己的matcher添加到Jest中。例如,假设你正在测试一个 theory library,并且你经常断言数字可以被其他数整除,你可以把它抽象成toBeDivisibleBy matcher。
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);expect({apples: 6, bananas: 3}).toEqual({apples: expect.toBeDivisibleBy(2),bananas: expect.not.toBeDivisibleBy(2),});
});
expect.extends还支持异步匹配器,异步匹配器返回一个promise,因此你需要等待返回的值。让我们使用一个示例matcher来说明它们的用法。我们要实现一个非常相似的matcher,而不是toBeDivisibleBy,唯一的区别是可分割的数字将从外部源中提取。
expect.extend({async toBeDivisibleByExternalValue(received) {const externalValue = await getExternalValueFromRemoteSource();const pass = received % externalValue == 0;if (pass) {return {message: () =>`expected ${received} not to be divisible by ${externalValue}`,pass: true,};} else {return {message: () =>`expected ${received} to be divisible by ${externalValue}`,pass: false,};}},
});test('is divisible by external value', async () => {await expect(100).toBeDivisibleByExternalValue();await expect(101).not.toBeDivisibleByExternalValue();
});
匹配器应该返回带有两个键的对象(或对象的promise)。pass指示是否存在匹配,message提供了一个没有参数的函数,在失败时返回错误消息。因此当pass为false时,当expect(x). yourmatcher()失败时,消息应该返回错误消息。当pass为true时,消息应该返回expect(x).no . yourmatcher()失败时的错误消息。
this.equals(a, b)
如果两个对象具有相同的值(递归地),则返回true。this.utils有很多有用的工具,utils主要由来自jest-matcher-utils的导出组成。最有用的是matcherHint、printExpected和printReceived,它们可以很好地格式化错误消息。
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()
它匹配除null或undefined之外的任何内容。你可以在内部使用toEqual或toBeCalledWith而不是文字值。例如如果你想检查一个模拟函数是否被调用,它的参数是非空的:
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)
匹配给定构造函数所创建的任何内容。你可以在内部使用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)
匹配一个接收到的数组,该数组包含预期数组中的所有元素,也就是说预期数组是接收数组的子集,因此它匹配一个接收到的数组,该数组包含不属于预期数组的元素。
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)
验证在测试期间调用了一定数量的断言,在测试异步代码时这通常很有用,以便确保回调中的断言确实被调用。
假设我们有一个函数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.hasAssertions()
验证在测试期间至少调用了一个断言。在测试异步代码时,这通常很有用以便确保回调中的断言确实被调用。
假设我们有一些处理状态的函数,prepareState调用一个状态对象的回调,validateState运行在那个状态对象上,waitOnState返回一个承诺,直到所有prepareState回调完成。
test('prepareState prepares a valid state', () => {expect.hasAssertions();prepareState(state => {expect(validateState(state)).toBeTruthy();});return waitOnState();
});
expect.not.arrayContaining(array)
匹配所接收的数组,该数组不包含预期数组中的元素。也就是说,预期的数组不是接收数组的子集,它与 expect.arrayContaining 相反。
describe('not.arrayContaining', () => {const expected = ['Samantha'];it('matches if the actual array does not contain the expected elements', () => {expect(['Alice', 'Bob', 'Eve']).toEqual(expect.not.arrayContaining(expected),);});
});
expect.not.objectContaining(object)
匹配任何未递归地匹配预期属性的接收对象。也就是说预期对象不是接收对象的子集。因此,它匹配所接收的对象,该对象包含不属于预期对象的属性。它与expect. objectcontains相反。
describe('not.objectContaining', () => {const expected = {foo: 'bar'};it('matches if the actual object does not contain expected key: value pairs', () => {expect({bar: 'baz'}).toEqual(expect.not.objectContaining(expected));});
});
expect.not.stringContaining(string)
匹配不包含确切期望字符串的接收字符串,它与expect.stringContaining.相反。
describe('not.stringContaining', () => {const expected = 'Hello world!';it('matches if the actual string does not contain the expected substring', () => {expect('How are you?').toEqual(expect.not.stringContaining(expected));});
});
expect.not.stringMatching(string | regexp)
匹配不匹配预期regexp的接收字符串,它与expect.stringMatching.相反。
describe('not.stringMatching', () => {const expected = /Hello world!/;it('matches if the actual string does not match the expected regex', () => {expect('How are you?').toEqual(expect.not.stringMatching(expected));});
});
expect.objectContaining(object)
匹配递归地匹配预期属性的任何接收对象。也就是说,预期对象是接收对象的子集。因此,它匹配所接收的对象,该对象包含不属于预期对象的属性。
与期望对象中的文字属性值不同,您可以使用matchers、expect.anything()等等。假设我们希望使用事件对象调用onPress函数,我们需要验证的是事件是否有event.x属性和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.stringMatching(string | regexp)
匹配与预期regexp匹配的接收字符串,你可以用它代替文字的值:
- 在toEqual或toBeCalledWith
- 匹配arraycontains中的元素
- 匹配objectContaining 或者toMatchObject的属性
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),);});
});
.toBe(value)
toBe只是检查一个值是否符合您的期望。如果它使用的是对象,则是要检查完全相等。
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');});
});
.toEqual(value)
如果要检查两个对象是否具有相同的值,请使用. toequal。此matcher递归地检查所有字段的相等性,而不是检查对象标识——这也称为“深度相等”。例如,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);});
});
.toMatchObject(object)
使用. tomatchobject检查一个JavaScript对象是否匹配一个对象的属性子集。它将把接收到的对象与预期对象中没有的属性匹配起来。
您还可以传递一个对象数组,在这种情况下,只有当接收到的数组中的每个对象(在上面描述的番茄对象意义中)与预期数组中的相应对象相匹配时,该方法才会返回true。如果想要检查两个数组在它们的元素数量上是否匹配,而不是arrayinclude,这是非常有用的,因为它允许在接收的数组中添加额外的元素。
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中是否存在对象的属性。要检查对象中深度嵌套的属性,可以使用点表示法或包含深度引用的keyPath的数组。
可选地,你可以提供一个值来检查它是否等于目标对象的keyPath中的值。此matcher使用“深度相等”(如toEqual()))并递归地检查所有字段的相等性。
下面的示例包含一个带有嵌套属性的houseForSale对象。我们使用tohave属性来检查对象中各种属性的存在性和值。
const houseForSale = {bath: true,bedrooms: 4,kitchen: {amenities: ['oven', 'stove', 'washer'],area: 20,wallColor: 'white','nice.oven': true,},
};test('this house has my desired features', () => {// Simple Referencingexpect(houseForSale).toHaveProperty('bath');expect(houseForSale).toHaveProperty('bedrooms', 4);expect(houseForSale).not.toHaveProperty('pool');// Deep referencing using dot notationexpect(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 keyPathexpect(houseForSale).toHaveProperty(['kitchen', 'area'], 20);expect(houseForSale).toHaveProperty(['kitchen', 'amenities'],['oven', 'stove', 'washer'],);expect(houseForSale).toHaveProperty(['kitchen', 'amenities', 0], 'oven');expect(houseForSale).toHaveProperty(['kitchen', 'nice.oven']);expect(houseForSale).not.toHaveProperty(['kitchen', 'open']);
});
其他:
前端单元测试之Jest
React测试框架之enzyme
Jest测试语法系列之Globals
Jest测试语法系列之Matchers
Jest测试语法系列之Expect相关推荐
- Jest测试语法系列之Globals
在上一篇文章中,我们主要介绍了Jest测试框架语法系列之Matchers的相关内容,本篇主要涉及的是Global Functions(全局函数),也是官方提供给开发者的核心功能之一.官方API地址为: ...
- 前端测试框架Jest系列教程 -- Expect(验证)
写在前面 在编写测试时,我们通常需要检查值是否满足某些条件,Jest中提供的expect允许你访问很多"Matchers",这些"匹配器"允许您验证不同的东西. ...
- 使用Jest测试JavaScript (入门篇)
1 什么是 Jest? Jest是 Facebook 的一套开源的 JavaScript 测试框架, 它自动集成了断言.JSDom.覆盖率报告等开发者所需要的所有测试工具,是一款几乎零配置的测试框架. ...
- react jest测试_如何使用React测试库和Jest开始测试React应用
react jest测试 Testing is often seen as a tedious process. It's extra code you have to write, and in s ...
- 使用Jest测试JavaScript (入门篇) 1
1 什么是 Jest? Jest Jest是 Facebook 的一套开源的 JavaScript 测试框架, 它自动集成了断言.JSDom.覆盖率报告等开发者所需要的所有测试工具,是一款几乎零配置的 ...
- Jest测试框架学习(一)
前言 jest是针对JavaScript的测试框架.如果遵循TDD原则,在任何功能开发之前都需要先写测试.而测试分为单元测试,集成测试和系统测试. 单元测试 单元测试可以理解为对于单个函数(单一功能) ...
- jest测试具体方法
一.基本语法(匹配器matchers) 1.基础语法 test('two plus two is four', () => {expect(2 + 2).toBe(4); }); expect( ...
- jest测试ajax,ajax – 如何使用Jest来测试React呈现的异步数据?
我正在使用React for render和Jest / Jasmine进行测试.我使用旧的Jest / Jasmine等待测试并运行,但现在这些已经在Jasmine 2中消失了,我不知道如何用新的a ...
- react jest测试_如何使用Jest和react-testing-library测试Socket.io-client应用程序
react jest测试 by Justice Mba 由Mba法官 如何使用Jest和react-testing-library测试Socket.io-client应用程序 (How to test ...
最新文章
- ios mysql 修改数据,iOS数据库FMDB--增删改查(模糊查询)实写记录
- idea中properties配置文件没有代码提示及代码高亮问题解决方案
- WPF数据绑定、多个元素
- Web框架之Django_10 重要组件(Auth模块)
- 优化mysql slave的同步速度
- 课程设计个人报告——基于ARM实验箱的捕鱼游戏的设计与实现
- 内存中发堆和栈,栈是运行时的单位,而堆是存储的单位
- 绕过 WAF:绕过一些 WAF 设备的 Burp 插件
- 基于C++的Qt网络编程——聊天客户端
- Amlogic机顶盒开发工具使用
- 1、使用xcode9创建swift语言的第一个程序hello world
- 交叉验证和超参数调整:如何优化你的机器学习模型
- 数学史思维导图_高中数学课堂教学中思维导图的制作运用
- PC平台最佳相片管理软件Picasa
- 正则表达式的语法汇总
- 南京电子地图下载 离线电子地图
- 平均随机一致性指标表MATLAB,AHP法中平均随机一致性指标的算法及MATLAB实现.pdf...
- 25 Three.js的点光源THREE.PointLight
- java游戏 超级酒吧女生,酒吧游戏你知道多少?22个游戏你玩过几个?
- oop 编程是什么?