2-10 Jest中的mock
为什么要使用Mock函数?
在项目中,一个模块的方法内常常会去调用另外一个模块的方法。在单元测试中,我们可能并不需要关心内部调用的方法的执行过程和结果,(因为异步请求的结果是后端来测试的,前端没必要等到结果返回,只需要关心是否调用了函数即可)只想知道它是否被正确调用即可,甚至会指定该函数的返回值。此时,使用Mock函数是十分有必要。
Mock函数提供的以下三种特性,在我们写测试代码时十分有用:
- 捕获函数调用情况
- 设置函数返回值
- 改变函数的内部实现
1. 捕获函数调用情况
例如:
demo.js
export const runCallback = (fn)=> {
fn();
}
demo.test.js
import { runCallback } from './demo';
test('测试runCallback', () => {
const func = () => {
return 'hello';
}
expect(runCallback(func)).toBe('hello');
})
造成上述原因是因为demo.js里的回调函数没有返回值,如果加上return就没有问题了
export const runCallback = (fn)=> {
return fn();
}
在我们测试一个函数的时候,这个函数可能没有返回值。这时候我们不能因为测试而改变我们的源代码函数,那怎么才能判断这个函数被调用了呢?这时候就要用到Jest提供的mock。
//demo.js
export const runCallback = (fn)=> {
fn();
}
// demo.test.js
import { runCallback } from './demo';
test('测试runCallback', () => {
const func = jest.fn();
console.log(func)
// runCallback(func)
expect(func).toBeCalled();
})
由于我们的runCallback并没有被执行,而我们期待的是runCallback被调用一次,所以报错了,如果我们把代码中runCallback(func)打开,那么就会通过测试。这就是捕获函数调用情况。
2. 设置函数返回值
//demo.js
export const runCallback = (fn)=> {
fn();
}
//demo.test.js
import { runCallback } from './demo';
test('测试runCallback', () => {
const func = jest.fn().mockReturnValue('123');
expect(func(runCallback(func))).toBe('123');
})
3. 改变函数的内部实现
// demo.js
import axios from 'axios';
export const getData = () => {
return axios.get('/api').then(res => {
return res.data;
})
}
// demo.test.js
import { getData } from './demo';
import axios from 'axios'
jest.mock('axios');
test.only('测试getData ', async () => {
axios.get.mockResolvedValue({
data: 'hello'
});
await getData().then(res => {
expect(res).toBe('hello');
})
})
补充:
我们可以通过 jest.fn(()=>{自定义函数})
来自定义一个jest.fn函数
参考链接:https://www.jianshu.com/p/ad87eaf54622