一 mock函数
在测试中没有提供测试用的数据,那么可以使用jest提供的mock函数,来捕获函数的调用。
const func = jest.fn(); //mock函数,捕获函数的调用
在mock函数里面包含了什么内容?我们可以通过console.log来查看
calls------ 函数被调用返回的结果
instances----- 函数指向的this原型
invocationCallOrder ------ 函数执行的顺序
results----- 函数执行的结果,为数组类型,有返回的类型和返回的值
console.log(func.mock);
{ calls: [ [ 'abc' ], [ 'abc' ] ], //函数被调用返回的结果
instances: [ undefined, undefined ],
invocationCallOrder: [ 1, 2 ], //函数执行的顺序
results: //函数执行的结果,为数组类型,有返回的类型和返回的值
[ { type: 'return', value: 'Dell' },
{ type: 'return', value: 'Dell' } ] }
{ calls: [ [] ],
instances: [ mockConstructor {} ], //函数指向的this原型
invocationCallOrder: [ 3 ],
results: [ { type: 'return', value: undefined } ] }
二 用mock写测试用例
证明:
- 捕获函数的调用和返回结果,以及this和调用顺序
- 它可以让我们自由地设置返回结果
编写需要测试的函数:
export const runCallback = (callback) => {
callback('abc');
}
export const createObject = (classItem) => {
new classItem();
}
编写测试用例:
import { runCallback, createObject } from './demo';
test('测试runCallback',()=>{
const func = jest.fn(); //mock函数,捕获函数的调用
//.mockReturnValueOnce 是指调用一次返回的值
// func.mockReturnValueOnce('Dell');
// func.mockReturnValueOnce('Lee');
// func.mockReturnValueOnce('Hello');
//.mockReturnValueOnce/链式调用
//func.mockReturnValueOnce('Dell').mockReturnValueOnce('Lee').mockReturnValueOnce('Hello');
//.mockReturnValue 指返回的所有的值
func.mockReturnValue('Dell');
//调用mock函数
runCallback(func);
runCallback(func);
// 测试用例
// expect(func).toBeCalled();
// expect(runCallback(func)).toBe('hello');
// expect(func.mock.calls.length).toBe(2);
expect(func.mock.calls[0]).toEqual(['abc']);
expect(func.mock.results[0].value).toBe('Dell');
console.log(func.mock);
});
test('测试 createObject', ()=>{
const func = jest.fn();
createObject(func);
console.log(func.mock);
});
证明:
- 它可以改变内部函数的实现
把异步获取数据的内容变成同步准备数据的内容(让axios同步地模拟数据,而不是真正的发起ajax请求)
编写请求函数
export const getData = () => {
return axios.get('https://rapi.qingting.fm/recommendations/0/channel_list?more=true&replay=false').then(res =>res.data)
}
编写测试用例
import axios from 'axios';
jest.mock('axios'); //mock模拟整个axios
test.only('测试 getData', async ()=>{
//单次请求返回
axios.get.mockResolvedValueOnce({data: 'hello'})
//多次请求返回
axios.get.mockResolvedValueOnce({data: 'world'})
//不希望发真正的ajax请求
await getData().then((data) => {
expect(data).toBe('hello');
})
await getData().then((data) => {
expect(data).toBe('world');
})
});
三 小技巧
关于mock返回的内容
const func = jest.fn(()=>{
return '456'
});
//相当于
func.mockReturnValue('Dell');
或者是
func.mockReturnValueOnce('Dell');
比两者提供的功能更强的是:
func.mockImplementationOnce(() => {
console.log('122');
return 'Dell'
}); //单个调用的单次返回
func.mockImplementation(() => {
console.log('122');
return 'Dell'
}); //调用之后返回的全部内容
//不希望返回任何内容
func.mockImplementation(() => {
return this;
});
//相当于
func.mockReturnThis();
expect(func.mock.results[0].value).toBeUndefined();
//对于返回的值
expect(func.mock.calls[0]).toEqual(['abc']); //第一次返回的是 abc
expect(func).toBeCalledWith('abc'); //每一次返回的都应该是abc
四 小总结----mock函数的作用
- 捕获函数的调用和返回结果,以及this和调用顺序
- 它可以让我们自由地设置返回结果
- 它可以改变内部函数的实现