Jest学习记录
一、安装
npm isntall jest --global # 全局
npm install --save-dev jest # 项目
二、概念
1. Matchers
toBe, toEqual, not
test('two plus two is four', () => {
expect(2 + 2).toBe(4);
});
toBe 使用Object.is()来精确匹配
只想检查值得话使用toEqual()
not用来取反
test('object assignment', () => {
const data = {one: 1};
data['two'] = 2;
expect(data).toEqual({one: 1, two: 2});
});
test('not zero', () => {
let a = 1;
let b = 3;
expect(a + b).not.toBe(0);
});
Truthiness
如何区分null,undefined和false
- toBeNull
- toBeUndefined
- toBeDefined
- toBeTruthy
- toBeFalsy
数字
对于浮点数使用toBeCloseTo()
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);
// float
const v = 0.1 + 0.2;
expect(v).toBeCloseTo(0.3);
})
字符串
toMatch()匹配正则表达式
test('there is a "stop" in the word', function () {
expect('Christoph').toMatch(/stop/);
})
Array & Iterables
toContain()是否包含
const arr = [1,3,5,7,9];
test('not contain 6', function () {
arr.not.toContain(6);
})
Exceptions
toThrow()测试报错
function myCode(){
throw new Error('any error');
}
test('any error', function () {
expect(myCode).toThrow();
})
2. Asynchronous
Callback
done()等待回调完成
test('the data is peanut butter', done => {
function callback (data) {
try {
expect(data).toBe('peanut butter');
done(); // jest callback flag
} catch (error) {
done(error);
}
}
fetchData(callback);
})
Promise
返回一个Promise
test('peanut butter', () => {
return fetchData().then(data => {
expect(data).toBe('peanut butter');
});
});
test('the fetch fails with an error', () => {
expect.assertions(1);
return fetchData().catch(e => expect(e).toMatch('error'));
});
.resolves/.rejects
test('peanut butter', () => {
return expect(fetchData()).resolves.toBe('peanut butter');
});
test('error', () => {
return expect(fetchData()).rejects.toMatch('error');
});
async/await
最简洁,最推荐
test('peanut butter', async () => {
const data = await fetchData();
expect(data).toBe('peanut butter');
});
test('error', async() => {
expect.assertions(1);
try {
await fetchData();
} catch (e) {
expect(e).toMatch('error');
}
});
混合使用
test('data', async() => {
await expect(fetchData()).resolves.toBe('data');
});
test('error', async() => {
await expect(fetchData()).rejects.toThrow('error');
});
3. Setup & Teardown
多次重复设置
beforeEach( () => {
// do something
});
afterEach( () => {
// do something
});
一次性设置
beforAll( () => { /* ... */});
afterAll( () => { /* ... */});
describe
在真正测试开始之前,先执行所有describe handlers
仅运行某一条测试
test.only('only test', () => { /*...*/});
4. Mock Function
.mock
所有mock函数都有.mock
属性,保存调用相关信息
const myMock = jest.fn();
myMock.mock.instances; // this指向
myMock.mock.calls; // 调用,参数信息
myMock.mock.results; // 返回值
mockReturnValue 模拟返回值
连续传递风格continuation-passing style
mockReturnValueOnce()
const filterTestFun = jest.fn();
filterTestFun.mockReturnValueOnce(true).mockReturnValue(false);
模拟模块
测试方法而不实际调用API(使测试变得缓慢,脆弱)
// users.js
import axios from 'axios';
class Users {
static all() {
return axios.get('/user.json').then(resp => resp.data);
}
}
export default Users;
// users.test.js
import axios from 'axios';
import Users from './users.js';
jest.mock('axios');
test('should fetch users', () => {
const users = [{name: 'Bob'}];
const resp = {data: users};
axios.get.mockResolvedValue(resp);
return Users.all().then(data => expect(data).toEqual(users));
});
模拟实现
jest.fn() 和 mockImplementationOnce()
const myMockFn = jest
.fn(() => 'default)
.mockImplementationOnce( () => 'first call')
.mockImplementationOnce( () => 'second call');
// 返回this的链式调用
jest.fn().mockReturnThis();
jest.fn(function () {
return this;
})
具名模拟
mockName(‘name’)
const myMockFn = jest
.fn()
.mockName('mockFunction');