博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Jest 断言归纳
阅读量:4085 次
发布时间:2019-05-25

本文共 7014 字,大约阅读时间需要 23 分钟。

Jest 实在是很方便,上手简单,几乎零配置。记录一下学习 Jest matchers。附上大部分说明及示例。

普通匹配器

  • toBe - toBe 使用 Object.is 来测试是否完全相等
  • .not - 用来测试相反的用例
  • .toEqual - 如果你想检查某个对象的值,请改用 toEqual。

toBe

最简单的测试值的方法是看是否精确匹配。

test('two plus two is four', () => {     expect(2 + 2).toBe(4); });

toEqual

如果你想检查某个对象的值,请改用 toEqual。

test('object assignment', () => {     const data = {one: 1};     data['two'] = 2;      expect(data).toEqual({one: 1, two: 2}); });

.not

用来测试相反的用例

test('null', () => {  const n = null;  expect(n).not.toBeUndefined();  expect(n).not.toBeTruthy();});

布尔值匹配器

  • toBeNull 只匹配 null
  • toBeUndefined 只匹配 undefined
  • toBeDefined 与 toBeUndefined 相反
  • toBeTruthy 匹配任何 if 语句为真
  • toBeFalsy 匹配任何 if 语句为假
test('null', () => {  const n = null;  expect(n).toBeNull();  expect(n).toBeDefined();  expect(n).not.toBeUndefined();  expect(n).not.toBeTruthy();  expect(n).toBeFalsy();});test('zero', () => {  const z = 0;  expect(z).not.toBeNull();  expect(z).toBeDefined();  expect(z).not.toBeUndefined();  expect(z).not.toBeTruthy();  expect(z).toBeFalsy();});

数字匹配器

  • .toBeGreaterThan() - 大于
  • .toBeGreaterThanOrEqual() 大于等于
  • .toBeLessThan() - 小于
  • .toBeLessThanOrEqual() - 小于等于
  • .toBeCloseTo() - 浮点数比较

toBeGreaterThan、toBeGreaterThanOrEqual、toBeLessThan、toBeLessThanOrEqual

test('two plus two', () => { const value = 2 + 2;  expect(value).toBeGreaterThan(3);  expect(value).toBeGreaterThanOrEqual(3.5);  expect(value).toBeLessThan(5);  expect(value).toBeLessThanOrEqual(4.5);// toBe 和 toEqual 对于数字来说是一样的 expect(value).toBe(4);  expect(value).toEqual(4); });

.toBeCloseTo()

对于比较浮点数的相等,应该使用 toBeCloseTo

test('两个浮点数字相加', () => {    const value = 0.1 + 0.2;        // 0.30000000000000004     expect(value).toBe(0.3);        // 这句会报错,因为 js 浮点数有舍入误差    expect(value).toBeCloseTo(0.3); // 这句可以运行});

字符串匹配器

  • toMatch - 正则表达式的字符
  • .toHaveLength(number) - 判断一个有长度的对象的长度

toMatch

正则表达式的字符

test('there is no I in team', () => {  expect('team').not.toMatch(/I/);});test('but there is a "stop" in Christoph', () => {  expect('Christoph').toMatch(/stop/);});

.toHaveLength(number)

判断一个有长度的对象的长度

expect([1, 2, 3]).toHaveLength(3);expect('abc').toHaveLength(3);expect('').not.toHaveLength(5);

数组匹配器

  • .toContain(item) - 判断数组是否包含特定子项
  • .toContainEqual(item) - 判断数组中是否包含一个特定对象

.toContain

判断数组是否包含特定子项

const shoppingList = [  'diapers',  'kleenex',  'trash bags',  'paper towels',  'beer',];test('购物清单(shopping list)里面有啤酒(beer)', () => {  expect(shoppingList).toContain('beer');});

.toContainEqual(item)

可以判断数组中是否包含一个特定对象,类似 toEqual 与 toContain 的结合

function myBeverages() {    return [        {delicious: true, sour: false},        {delicious: false, sour: true}    ]}test('is delicious and not sour', () => {    const myBeverage = {delicious: true, sour: false};    expect(myBeverages()).toContainEqual(myBeverage);});

对象匹配器

  • .toMatchObject(object) - 判断一个对象嵌套的 key 下面的 value 类型
  • .toHaveProperty(keyPath, value) - 判断在指定的 path 下是否有这个属性

.toMatchObject(object)

判断一个对象嵌套的 key 下面的 value 类型,需要传入一个对象。

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);});

.toHaveProperty(keyPath, value)

判断在指定的 path 下是否有这个属性,嵌套的 path 可以用 '.'分割,也可以用数组。

// Object containing house features to be testedconst 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');  // 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']);});

自定义匹配器

使用expect.extend将自己的匹配器添加到Jest。自定义匹配器需要返回一个包含两个key 的对象

{    pass:false //‘布尔值’,     message: () => 'message string' //‘函数,该函数返回一个提示信息’}
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);});

这些帮助函数可以在自定义匹配器中的this中找到:

  • this.isNot
  • this.equals(a, b)
  • this.utils(matcherHint, printExpected and printReceived)

其他

  • toThrow - 要测试的特定函数会在调用时抛出一个错误
  • .resolves 和 .rejects - 用来测试 promise
  • .toHaveBeenCalled() - 用来判断一个函数是否被调用过
  • .toHaveBeenCalledTimes(number) - 判断函数被调用过几次

toThrow

要测试的特定函数会在调用时抛出一个错误

function compileAndroidCode() {  throw new ConfigError('you are using the wrong JDK');}test('compiling android goes as expected', () => {  expect(compileAndroidCode).toThrow();  expect(compileAndroidCode).toThrow(ConfigError);  // You can also use the exact error message or a regexp  expect(compileAndroidCode).toThrow('you are using the wrong JDK');  expect(compileAndroidCode).toThrow(/JDK/);});

.resolves 和 .rejects

用来测试 promise

//resolvestest('resolves to lemon', () => {  // make sure to add a return statement  return expect(Promise.resolve('lemon')).resolves.toBe('lemon');});//rejectstest('resolves to lemon', async () => {  await expect(Promise.resolve('lemon')).resolves.toBe('lemon');  await expect(Promise.resolve('lemon')).resolves.not.toBe('octopus');});

.toHaveBeenCalled()

.toHaveBeenCalled() 也有个别名是.toBeCalled(),用来判断一个函数是否被调用过。

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)

和 toHaveBeenCalled 类似,判断函数被调用过几次。

test('drinkEach drinks each drink', () => {  const drink = jest.fn();  drinkEach(drink, ['lemon', 'octopus']);  expect(drink).toHaveBeenCalledTimes(2);});

未整理部分

lastCalledWith

toBeCalledWith

toHaveBeenCalledWith

toHaveBeenLastCalledWith

toBeInstanceOf

toMatchSnapshot

toThrowError

toThrowErrorMatchingSnapshot

 

10人点赞

 

 

作者:woodccc
链接:https://www.jianshu.com/p/c1b5676c1edd
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

你可能感兴趣的文章
专业和业余的区别就在于你在基础在基本功打磨练习花的时间
查看>>
通过mavlink实现自主航线的过程笔记
查看>>
Ardupilot飞控Mavlink代码学习
查看>>
这些网站有一些嵌入式面试题合集
查看>>
我觉得刷题是有必要的,不然小心实际被问的时候懵逼,我觉得你需要刷个50份面试题。跟考研数学疯狂刷卷子一样!
查看>>
我觉得嵌入式面试三要素:基础吃透+项目+大量刷题,缺一不可。不刷题是不行的。而且得是大量刷,刷出感觉套路,别人做题都做得是固定题型套路条件反射了,你还在那慢慢理解慢慢推是不行的,也是考研的教训。
查看>>
相机标定的目的:获取摄像机的内参和外参矩阵(同时也会得到每一幅标定图像的选择和平移矩阵),内参和外参系数可以对之后相机拍摄的图像就进行矫正,得到畸变相对很小的图像。
查看>>
现在来看,做个普罗米修斯的docker镜像对我而言并不难,对PX4仿真环境配置也熟悉了。
查看>>
删除docker容器和镜像的命令
查看>>
VINS-Fusion Intel® RealSense™ Depth Camera D435i
查看>>
使用Realsense D435i运行VINS-Fusion并建图
查看>>
gazebo似乎就是在装ROS的时候一起装了,装ROS的时候选择的是ros-melodic-desktop-full的话。
查看>>
React + TypeScript 实现泛型组件
查看>>
TypeScript 完全手册
查看>>
React Native之原理浅析
查看>>
Git操作清单
查看>>
基础算法
查看>>
前端面试
查看>>
React Hooks 异步操作踩坑记
查看>>
聊聊编码那些事,顺带实现base64
查看>>