领取jest急救包

250 阅读2分钟

快速学习使用 jest, 让你单测100%。

快速植入项目

npm install --save-dev jest

增加下列段落到 -- package.json:

{

"scripts": {

"test": "jest"

}

}

文件名编写xxx.test.js

情景

写单测

describe(name, fn) : 是一个将多个相关的测试组合在一起的块。

test(name, fn): 测试某个场景的代码块。

expect(): 匹配器,检查值是否满足某些条件。

describe('My work', () => {
  test('works', () => {
    expect(2).toEqual(2)
  })
})

常用的匹配器

expect(value).toBe()

expect(value).toHaveLength()

expect(drink).toHaveBeenCalledWith()

跳过测试

跳过某些代码块和不通过代码块,只是想保留这行代码。

describe.skip(name, fn); 
it.skip(name, fn)

周期函数

执行所有的单测前,执行的函数

afterAll(fn, timeout);

describe代码块内执行的函数

afterEach(fn, timeout);

相反的是

beforeAll(fn, timeout);

beforeEach(fn, timeout);

基本期望

expect(value)
  .not //不是这个值
  .toBe(value) // 等于某个值
  .toEqual(value) // 等于某个值
  .toBeTruthy() // value is true

请注意,这toEqual是一个深度相等检查

快照

expect(value)
  .toMatchSnapshot() // 生成文件,记录值得现状。
  .toMatchInlineSnapshot() // 对比局部快照

请注意,toMatchInlineSnapshot()需要为项目设置 Prettier

错误

expect(value)
  .toThrow(error)// 捕获错误
  .toThrowErrorMatchingSnapshot()

布尔值

expect(value)
  .toBeFalsy() // 值为false
  .toBeNull() // 值为null
  .toBeTruthy() // 值为ture
  .toBeUndefined() // 值不为undefined
  .toBeDefined()

数字

expect(value)
  .toBeCloseTo(number, numDigits) // 接近某个值,二参数是几位小数点
  .toBeGreaterThan(number) // 大于
  .toBeGreaterThanOrEqual(number) // 大于等于
  .toBeLessThan(number) // 小于不超过
  .toBeLessThanOrEqual(number) // 小于不超过且等于

对象

expect(value)
  .toBeInstanceOf(Class)
  .toMatchObject(object)
  .toHaveProperty(keyPath, value)

对象

expect(value)
  .toContain(item)检查项目是否在数组中时使用
  .toContainEqual(item)
  .toHaveLength(number)检查项目是否在数组长度

字符串

expect(value)
  .toMatch(regexpOrString) 检查字符串是否与正则表达式匹配

// for exmaple

  expect('grapefruit').toMatch(/grapefruit/);

其他

expect.extend(matchers) 将自己的匹配器添加到 Jest 扩展 
// for example
expect.extend({
  toBeWithinRange(received, floor, ceiling) {
    const pass = received >= floor && received <= ceiling;
    if (pass) {
      return {
        message: () =>
          `expected ${received} not to be within range ${floor} - ${ceiling}`,
        pass: true,
      };
    } else {
      return {
        message: () =>
          `expected ${received} to be within range ${floor} - ${ceiling}`,
        pass: false,
      };
    }
  },
});

test('numeric ranges', () => {
  expect(100).toBeWithinRange(90, 110);
  expect(101).not.toBeWithinRange(0, 100);
  expect({apples: 6, bananas: 3}).toEqual({
    apples: expect.toBeWithinRange(1, 10),
    bananas: expect.not.toBeWithinRange(11, 20),
  });
});

//-----------//


expect.any(constructor)
expect.addSnapshotSerializer(serializer)

expect.assertions(1) // 验证在测试期间是否调用了一定数量的断言。这在测试异步代码时通常很有用,以确保回调中的断言实际被调用。

异步测试 : 一般测试异步代码使用,如果组件含有setTimeout定时器这类的代码可以通过下面的代码处理。

test('works with promises', () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {resolve()}, 2000);
  })
})
test('works with async/await', async () => {
  const hello = await foo()
  ···
})

返回承诺,或使用 async/await.

快照

it('works', () => {
  const output = something()
  expect(output).toMatchSnapshot()
})

计时器

jest.useFakeTimers()
it('works', () => {
  jest.runOnlyPendingTimers()
  jest.runTimersToTime(1000)
  jest.runAllTimers()
})

模拟函数

const fn = jest.fn()
const fn = jest.fn(n => n * n)

返回值

const fn = jest.fn(() => 'hello')

或者:

jest.fn().mockReturnValue('hello')
jest.fn().mockReturnValueOnce('hello')