Jest 是一个用于 JavaScript 应用的测试框架。它提供了一系列强大的特性,例如断言、mock 函数、snapshot 等等。在本文中,我们将重点讨论在 Jest 中使用 mock 函数的最佳实践,包括基础用法、高级用法和一些值得注意的问题。
基础用法
在 Jest 中,Mock 函数可以通过 jest.fn() 函数来创建。例如:
const mockFn = jest.fn();
然后我们可以使用 mockFn() 来调用这个 Mock 函数,以捕获函数调用和返回值等信息。例如:
mockFn('param1', 'param2'); console.log(mockFn.mock.calls); // 输出 [['param1', 'param2']]
其中,mock.calls 表示函数调用列表。我们可以检查调用列表是否符合预期。例如:
expect(mockFn.mock.calls[0]).toEqual(['param1', 'param2']); expect(mockFn).toHaveBeenCalledWith('param1', 'param2'); expect(mockFn).toHaveBeenCalledTimes(1);
这些断言可以帮助我们检查 Mock 函数是否已按预期被调用。
高级用法
除了上述基础用法外,Jest 还提供了许多高级用法,例如 Mock 模块、手动 Mock、Mock 定时器、Mock API 等等。接下来,我们将为您详细介绍这些高级用法,并演示如何使用它们。
Mock 模块
Mock 模块是一个以模块为单位的 Mock 函数。我们使用 jest.mock() 函数来 Mock 模块。
例如,假设有一个 App.js 模块:
// App.js import { fetchData } from './api'; function App() { const data = fetchData(); // ... }
我们可以使用 jest.mock() 函数来 Mock api.js 模块:
-- -------------------- ---- ------- -- --------------------- ------ --- ---- --------- ------ - --------- - ---- --------- -------------------- --------- ----- ------ -- -- - ----------------------------- ----- ------- --- ----- - --------- - - ----------- ---- ----- ---------- -- -------------------- ------------------------------------------- ---
在这个示例中,我们 Mock 了 fetchData() 函数,并在测试中使用 mockResolvedValue() 函数指定它的返回值。然后我们渲染了 App 组件,并等待其显示出来。最后,我们检查 fetchData() 函数是否已按预期被调用。
手动 Mock
有时候,我们需要手动编写 Mock 函数来模拟第三方库或 API。在 Jest 中,我们可以使用 jest.mock() 函数手动 Mock 任何东西。
例如,假设有一个使用 axios 库发送请求的 api.js 模块:
// api.js import axios from 'axios'; export function fetchData() { return axios.get('/data'); }
我们可以手动编写 Mock 函数来模拟 axios 库的行为:
// __mocks__/axios.js const mockAxios = jest.genMockFromModule('axios'); mockAxios.get.mockImplementation(() => Promise.resolve({ data: 'dummy' }) ); export default mockAxios;
然后我们使用 jest.mock() 函数来 Mock api.js 模块:
-- -------------------- ---- ------- -- --------------------- ------ - --------- - ---- --------- ------------------- --------- ----- ------ ----- -- -- - ----- --- - ----- ------------ --------------------- ----- ------- --- ---
在这个示例中,我们手动 Mock 了 axios 库,并在测试中使用 fetchData() 函数来验证它是否正常工作。
Mock 定时器
有时候,我们需要在测试中 Mock 定时器,例如 setTimeout()、setInterval() 以及 requestAnimationFrame() 等等。在 Jest 中,我们可以使用 jest.useFakeTimers() 函数来 Mock 定时器。
例如,假设有一个使用 setTimeout() 定时器的 Delay.js 模块:
// Delay.js export function delay(ms) { return new Promise((resolve) => { setTimeout(() => { resolve(); }, ms); }); }
我们可以使用 jest.useFakeTimers() 函数来 Mock 定时器的行为:
-- -------------------- ---- ------- -- ----------------------- ------ - ----- - ---- ----------- ------------ -- - --------------------- --- ----------- -- - --------------------- --- --------- ------- -- -- - ----- ------- - ------------ ------------------------------- ------ -------- ---
在这个示例中,我们使用 jest.useFakeTimers() 函数 Mock 了定时器,然后使用 jest.advanceTimersByTime(1000) 函数让定时器直接执行回调函数。最后,我们使用 return promise 语句来确保测试函数不会退出太早。
Mock API
最后,我们讨论一下如何使用 Mock API。Mock API 可以帮助我们快速测试 API 调用的正确性,而不必进行实际的网络请求。
假设有一个使用 axios 库发送请求的 api.js 模块:
// api.js import axios from 'axios'; export function fetchData() { return axios.get('/data'); }
我们可以使用 axios-mock-adapter 库来 Mock axios 库的行为:
-- -------------------- ---- ------- -- --------------------- ------ ----- ---- -------- ------ ----------- ---- --------------------- ------ - --------- - ---- --------- ----- ---- - --- ------------------- --------- ----- ------ ----- -- -- - ------------------------------ - ----- ------- --- ----- --- - ----- ------------ --------------------- ----- ------- --- ---
在这个示例中,我们使用 MockAdapter 类来 Mock 网络请求,并使用 onGet() 函数来指定请求的 URL 和返回的结果。最后,我们使用 fetchData() 函数来验证它是否正常工作。
结论
我们已经深入了解了在 Jest 中使用 Mock 函数的最佳实践,包括基础用法、高级用法和一些值得注意的问题。接下来,我们应该在我们的项目中使用这些实践来编写更好的测试用例,并确保代码质量和稳定性。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/672188362e7021665e07d98d