在前端开发中,我们常常需要对接口数据进行测试,而有时候接口数据并没有直接返回或者返回的数据不符合我们的需求。这时候,我们可以使用 Jest 中的 mock 函数进行数据模拟,检查代码是否按预期运行。
什么是 mock 函数?
mock 函数就是一种虚拟函数,它可以在测试过程中替代真实的函数,并模拟出我们需要的行为和数据。在 Jest 中,我们可以使用 jest.fn()
创建一个模拟函数。
例如,我们有如下代码:
function fetchData() { return fetch('https://api.example.com/data').then(res => res.json()); }
我们可以使用 mock 函数模拟 fetchData
函数,将返回值固定为 {name: 'Tom', age: 18}
,如下:
jest.mock('./fetchData'); const fetchData = require('./fetchData'); test('fetchData should return {name: "Tom", age: 18}', async () => { fetchData.mockResolvedValue({name: 'Tom', age: 18}); const data = await fetchData(); expect(data).toEqual({name: 'Tom', age: 18}); });
这样,在测试过程中,fetchData
函数就会被 mock 函数代替,返回值固定为 {name: 'Tom', age: 18}
。
模拟函数的返回值
在 Jest 中,我们一般使用 mockResolvedValue
来模拟异步函数的返回值,使用 mockReturnValue
来模拟同步函数的返回值。
例如,我们有如下代码:
async function fetchData() { const res = await fetch('https://api.example.com/data'); const data = await res.json(); return data; }
我们可以使用 mockResolvedValue
,将返回值固定为 {name: 'Tom', age: 18}
,如下:
jest.mock('./fetchData'); const fetchData = require('./fetchData'); test('fetchData should return {name: "Tom", age: 18}', async () => { fetchData.mockResolvedValue({name: 'Tom', age: 18}); const data = await fetchData(); expect(data).toEqual({name: 'Tom', age: 18}); });
如果我们要模拟同步函数的返回值,例如 add
函数:
function add(a, b) { return a + b; }
我们可以使用 mockReturnValue
,将返回值固定为 10
,如下:
jest.mock('./add'); const add = require('./add'); test('add(3, 7) should return 10', () => { add.mockReturnValue(10); const result = add(3, 7); expect(result).toBe(10); });
模拟函数的调用
除了模拟函数的返回值,我们还可以检查函数是否被正确调用,并检查调用时传入的参数是否正确。在 Jest 中,我们可以使用 toHaveBeenCalled
、toHaveBeenCalledWith
等方法来检查函数的调用情况。
例如,我们有如下代码:
function fetchData(query) { return fetch(`https://api.example.com/search?q=${query}`).then(res => res.json()); }
我们可以使用 jest.fn()
模拟 fetchData
函数,然后检查它是否被正确调用,如下:
test('fetchData should be called with query "hello"', async () => { const fetchData = jest.fn(); fetchData.mockResolvedValue({results: ['hello world']}); const query = 'hello'; const data = await fetchData(query); expect(fetchData).toHaveBeenCalled(); expect(fetchData).toHaveBeenCalledWith(query); });
在测试过程中,我们模拟了 fetchData
函数,并将返回值固定为 {results: ['hello world']}
。然后,我们调用 fetchData
函数,并传入参数 query
,最后检查 fetchData
函数是否被正确调用,并且是否被传入了参数 query
。
模拟模块的导出对象
在 Jest 中,我们可以使用 jest.mock()
,模拟模块的导出对象,并将模拟函数赋值给模块的导出对象,如下:
-- -------------------- ---- ------- -- ------- ------ ----- --- - --- -- -- - - -- -- ------- -------------------- ----- - --- - - ------------------ --------- ------ ------ ---- -- -- - ------------------------- -- ---- ----- ------ - ------ --- ------------------------ ---
在测试过程中,我们将 math.js
模块的导出对象使用 jest.mock()
进行了模拟,并将模拟函数 add
赋值给导出对象中的同名函数。然后,我们在测试中使用 add.mockImplementation()
进行实现的模拟,将其返回值固定为 10
。
总结
使用 mock 函数进行数据模拟,可以帮助我们对接口数据进行测试,从而提高代码的可靠性和稳定性。在 Jest 中,我们可以使用 jest.fn()
创建模拟函数,使用 mockResolvedValue
、mockReturnValue
等方法模拟函数的返回值,并使用 toHaveBeenCalled
、toHaveBeenCalledWith
等方法检查函数的调用情况,从而实现 mock 函数的数据模拟。
参考文献
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6470171d968c7c53b0e3b996