新建 using-matchers.test.js 测试文件
// using-matchers.test.js
// toBe 使用 Object.is 来测试精确相等
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('adding positive numbers is not zero', () => {
for (let a = 1; a < 10; a++) {
for (let b = 1; b < 10; b++) {
expect(a + b).not.toBe(0);
}
}
});
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();
});
// 大多数的比较数字有等价的匹配器。
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 and toEqual are equivalent for numbers
expect(value).toBe(4);
expect(value).toEqual(4);
});
// 对于比较浮点数相等,使用 toBeCloseTo 而不是 toEqual,因为你不希望测试取决于一个小小的舍入误差。
test('两个浮点数字相加', () => {
const value = 0.1 + 0.2;
//expect(value).toBe(0.3); 这句会报错,因为浮点数有舍入误差
expect(value).toBeCloseTo(0.3); // 这句可以运行
});
您可以检查对具有 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/);
});
const shoppingList = [
'diapers',
'kleenex',
'trash bags',
'paper towels',
'beer',
];
test('the shopping list has beer on it', () => {
expect(shoppingList).toContain('beer');
expect(new Set(shoppingList)).toContain('beer');
});
// 在所有测试开始之前调用(调用一次)
beforeAll(() => {
console.log('beforeAll init data ')
});
// 在所有测试用例执行完之后调用(一次)
afterAll(() => {
console.log('afterAll init data ')
});
// 在每个测试用例执行之前调用
beforeEach(() => {
console.log('beforeEach init data ')
});
// 在每个测试用来执行完之后调用
afterEach(() => {
console.log('afterEach clear data ')
});
test('test 1', () => {
});
test('test 2', () => {
});
使用 describe 函数 给测试用例进行分组
describe('普通配置器的案例组', () => {
// toBe 使用 Object.is 来测试精确相等
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});
});
// ....
});
describe('Truthiness匹配器的案例组', () => {
test('null', () => {
const n = null;
expect(n).toBeNull();
expect(n).toBeDefined();
expect(n).not.toBeUndefined();
expect(n).not.toBeTruthy();
expect(n).toBeFalsy();
});
// ...
});
// Applies to all tests in this file
beforeEach(() => {
console.log('在 下面所有的测试用例之前 执行')
});
// toBe 使用 Object.is 来测试精确相等
test('1.two plus two is four', () => {
expect(2 + 2).toBe(4);
});
// 如果您想要检查对象的值,请使用 toEqual, toEqual 递归检查对象或数组的每个字段。
test('2.object assignment', () => {
const data = {one: 1};
data['two'] = 2;
expect(data).toEqual({one: 1, two: 2});
});
describe('Truthiness匹配器的案例组', () => {
// Applies only to tests in this describe block
beforeEach(() => {
console.log('仅仅在 下面这一个测试用例之前 会执行')
});
test('3.null', () => {
const n = null;
expect(n).toBeNull();
expect(n).toBeDefined();
});
});
编写utils.js
const checkedLogin = (name, password) => {
if(name === 'admin' && password === '123456'){
return true
} else {
return false
}
}
// export default { checkedLogin } // es6 ok
module.exports= {
checkedLogin
}
编写mock-func.js
import utils from './utils.js'
export const login =(name, password, callback) => {
if(utils.checkedLogin(name, password)){
callback('登录成功'); // 编写测试模拟该函数被调用
} else {
callback('登录失败'); // 编写测试模拟该函数被调用
}
}
在 mock-func.test.js 编写单元测试(模拟回调函数如何被调用、调用时的参数和返回值的信息等)
import { login } from './mock-func.js'
describe('login 测试组', () => {
test('test login1 函数有返回结果', ()=> {
// 1.模拟登录的回掉函数
// const mockCallback = jest.fn(res => { // callback 函数接收到的参数
// return '登录返回的结果:' + res // callback 函数返回的结果
// });
const mockCallback = jest.fn()
.mockImplementation(res => { // callback 函数接收到的参数
return '登录返回的结果:' + res // callback 函数返回的结果
});
// 2.调用登录函数
login('admin', 1234, mockCallback)
// 3.判断 callback 函数被调用的次数
expect(mockCallback.mock.calls.length).toBe(1);
// 4.判断 callback 函数接收到的参数
expect(mockCallback.mock.calls[0]).toContain('登录失败'); // ["登录失败"]
// 5.判断 callback 函数返回的结果
expect(mockCallback.mock.results[0].value).toBe('登录返回的结果:登录失败');
// 6.判断 callback 是否被调用
expect(mockCallback).toHaveBeenCalled();
// 7.判断 callback 调用时传入的参数是:登录失败
expect(mockCallback).toHaveBeenCalledWith('登录失败');
})
// mock 没有返回值
test('test login2 函数没有返回结果', ()=> {
// 1.模拟登录的回掉函数
const mockCallback = jest.fn(); // 函数没有返回直接
// 2.调用登录函数
login('admin', 1234, mockCallback)
// 3.判断 callback 函数被调用的次数
expect(mockCallback.mock.calls.length).toBe(1);
// 4.判断 callback 函数接收到的参数
expect(mockCallback.mock.calls[0]).toContain('登录失败'); // ["登录失败"]
// 5.判断 callback 函数没有返回结果
expect(mockCallback.mock.results[0].value).toBeUndefined()
})
// mock 返回值
test('test login3 自定义函数的返回结果', ()=> {
// 1.模拟登录的回掉函数
const mockCallback = jest.fn()
mockCallback.mockReturnValueOnce('自定义函数的返回结果') // 函数只返回一次
// mockCallback.mockReturnValue('自定义函数的返回结果') // 函数可被调用多次,返回多次
// 2.调用登录函数
login('admin', 1234, mockCallback)
// 3.判断 callback 函数被调用的次数
expect(mockCallback.mock.calls.length).toBe(1);
// 4.判断 callback 函数接收到的参数
expect(mockCallback.mock.calls[0]).toContain('登录失败'); // ["登录失败"]
// 5.判断 callback 函数返回的结果
expect(mockCallback.mock.results[0].value).toBe('自定义函数的返回结果');
})
})
所有的 mock 函数都有这个特殊的 .mock
属性,它保存了关于此函数如何被调用、调用时的返回值的信息。 .mock
属性还追踪每次调用时 this
的值,
执行单元测试:yarn test
LiuJun-MacBook-Pro:jest liujun$ yarn test mock-func.js
yarn run v1.13.0
$ jest mock-fu
PASS ./mock-func.test.js
login 测试组
✓ test login1 函数有返回结果 (4 ms)
✓ test login2 函数没有返回结果
✓ test login3 自定义函数的返回结果
Test Suites: 1 passed, 1 total
Tests: 3 passed, 3 total
Snapshots: 0 total
Time: 1.832 s, estimated 2 s
Ran all test suites matching /mock-fu/i.
✨ Done in 3.59s.
LiuJun-MacBook-Pro:jest liujun$
在 mock-func.test.js 编写单元测试(模拟 utils 模块,模拟 utils.checkedLogin 函数的实现 )
import { login } from './mock-func.js'
// 1.jest.mock('./utils.js')
let utils = require('./utils.js') // import utils from './utils.js' // ok
// 2.mock 掉 ./utils.js 所有的函数
jest.mock('./utils.js') // 这两个导入顺序没有要求,但是不用再组里面导入
describe('login 测试组', () => {
// mock 模拟utils模块
test('test login4 模拟内部的函数(模块)', ()=> {
// 3.重新实现utils模块对应的函数
// utils.checkedLogin.mockResolvedValue(true) // ok
utils.checkedLogin.mockImplementation((name, passwrod )=> {
if(name === 'admin' && passwrod === '1234'){
return true
} else {
return false
}
})
// 4.模拟登录的回掉函数
const mockCallback = jest.fn()
mockCallback.mockReturnValueOnce('自定义函数的返回结果') // 函数只返回一次
// 5.调用登录函数
login('admin', '1234', mockCallback)
// 6.判断 callback 函数被调用的次数
expect(mockCallback.mock.calls.length).toBe(1);
// 7.判断 callback 函数接收到的参数
expect(mockCallback.mock.calls[0]).toContain('登录成功'); // ["登录失败"]
// 5.判断 callback 函数返回的结果
expect(mockCallback.mock.results[0].value).toBe('自定义函数的返回结果');
})
})
执行单元测试:yarn test
LiuJun-MacBook-Pro:jest liujun$ yarn test mock-func.js
yarn run v1.13.0
$ jest mock-fu
PASS ./mock-func.test.js
login 测试组
✓ test login1 函数有返回结果 (4 ms)
✓ test login2 函数没有返回结果
✓ test login3 自定义函数的返回结果
✓ test login4 模拟内部的函数(模块) (1 ms)
Test Suites: 1 passed, 1 total
Tests: 4 passed, 4 total
Snapshots: 0 total
Time: 1.832 s, estimated 2 s
Ran all test suites matching /mock-fu/i.
✨ Done in 3.59s.
LiuJun-MacBook-Pro:jest liujun$