0%

使用Jest、Enzyme等工具进行单元测试(中)

Jest 钩子函数

我们如果有一些工作是在每次跑测试用例之前或者结束的时候要做的。我们就需要使用Jest提供的beforeEachafterEach
如果我们只想跑一次的话,那么我们就要用Jest提供的beforeAllafterAll这两个函数会在所有测试用例开始之前,和全部结束之后调用。

我们可以通过具体代码看一下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
beforeEach(() => {
console.log('beforeEach');
})

afterEach(() => {
console.log('afterEach');
})

beforeAll(() => {
console.log('beforeAll');
})

afterAll(() => {
console.log('afterAll');
})

test('test', () => {
console.log('test');
})

test('test1', () => {
console.log('test1');
})

test('test2', () => {
console.log('test2');
})

输出结果

1
2
3
4
5
6
7
8
9
10
11
beforeAll
beforeEach
test
afterEach
beforeEach
test1
afterEach
beforeEach
test2
afterEach
afterAll

通过打印的内容我们就能很直观的看到,beforeAll和afterAll在整个测试文件的开头和结尾调用一次。beforeEach和afterEach会在每个测试用例的开始和结束都会调用。

Jest 作用域

我们可以用describe来将测试分组。当afterbeforedescribe内部的时候,只适用于该describe内部的测试,但是顶级的beforeEachafterEach也会作用在该describe内部的测试用例。但是顶部的beforeEach会比内部的先执行,顶部的afterEach会比内部的晚执行。具体可以看官网给的例子。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
beforeAll(() => console.log('1 - beforeAll'));
afterAll(() => console.log('1 - afterAll'));
beforeEach(() => console.log('1 - beforeEach'));
afterEach(() => console.log('1 - afterEach'));
test('', () => console.log('1 - test'));
describe('Scoped / Nested block', () => {
beforeAll(() => console.log('2 - beforeAll'));
afterAll(() => console.log('2 - afterAll'));
beforeEach(() => console.log('2 - beforeEach'));
afterEach(() => console.log('2 - afterEach'));
test('', () => console.log('2 - test'));
});

// 1 - beforeAll
// 1 - beforeEach
// 1 - test
// 1 - afterEach
// 2 - beforeAll
// 1 - beforeEach
// 2 - beforeEach
// 2 - test
// 2 - afterEach
// 1 - afterEach
// 2 - afterAll
// 1 - afterAll

describe 和 test 的执行顺序

Jest会在具体test代码块之前执行所有describe处理器部分,所以我们要将准备工作都放在before、after中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
describe('outer', () => {
console.log('describe outer-a');

describe('describe inner 1', () => {
console.log('describe inner 1');
test('test 1', () => {
console.log('test for describe inner 1');
expect(true).toEqual(true);
});
});

console.log('describe outer-b');

test('test 1', () => {
console.log('test for describe outer');
expect(true).toEqual(true);
});

describe('describe inner 2', () => {
console.log('describe inner 2');
test('test for describe inner 2', () => {
console.log('test for describe inner 2');
expect(false).toEqual(false);
});
});

console.log('describe outer-c');
});

// describe outer-a
// describe inner 1
// describe outer-b
// describe inner 2
// describe outer-c
// test for describe inner 1
// test for describe outer
// test for describe inner 2

Jest Mock函数

在平时,我们需要测试一些回调函数是否被调用,而我们不关心调用内部的执行过程和结果,这时我们就需要jest.fn来mock一个函数。

1
2
3
4
5
6
7
const mockCallback = jest.fn();
forEach([0, 1], mockCallback);

test('该模拟函数被调用了两次', () => {
// 此模拟函数被调用了两次
expect(mockCallback.mock.calls.length).toBe(2);
})

我们可以看看.mock的属性都有哪些。

  1. calls: 每次调用传入的参数
  2. instances: 每次调用时this的值,
  3. invocationCallOrder: 每次调用的执行顺序
  4. results: 每次调用的返回值

如果我们想要取调用的参数可以这样写
expect(mockCallback.mock.calls[0][0])这是第一次调用的参数。

还可以通过mockReturnValueOnce()mockReturnValue()来控制返回值。

对于API的调用,我们不必等待API的返回结果,因为这非常耗时,我们可以直接用jest.mock()来模拟axios模块,可为 .get 提供一个 mockResolvedValue ,它会返回假数据用于测试。 实际上,我们想让 axios.get(‘/users.json’) 有个假的 response。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import axios from 'axios';
import Users from './users';

jest.mock('axios');

test('should fetch users', () => {
const users = [{name: 'Bob'}];
const resp = {data: users};
axios.get.mockResolvedValue(resp);

// or you could use the following depending on your use case:
// axios.get.mockImplementation(() => Promise.resolve(resp))

return Users.all().then(data => expect(data).toEqual(users));
});

Jest Snapshot 快照

快照是我个人觉得非常有用的功能,一般用于测试配置文件,UI有没有改动。
我们先通过测试配置文件来讲解测试快照。之后会具体讲使用snapshot来测试UI组件。

snapshot的原理简单的来说,就是第一次测试的时候生成一个快照文件,第二次跑测试用例的时候,会与这个快照进行对比,如果有变化则测试不通过,当然你也可以更新快照,这时快照的内容就是你最新的改变。

Jest VSCode插件

推荐使用 Facebook官方出的 vscode-jest 插件。 安装完插件后,不用每次都手动输入jest命令。每次回自动执行测试用例。并在通过的测试用例前用绿色的小点表示,失败的为红色小点。