🚁

01Jest中为什么要mock fetch

注意

  • jest mock就是网络请求,dom,localstorage需要mock一下,避免环境问题,保证单元测试环境的独立性
  • jest-fetch-mock
  • jest-localstorage-mock
  • jsdom

配置文件config

import * as path from 'path'; const babelConfig = { presets: [ ['@babel/preset-env', { targets: { node: 'current' } }], '@babel/preset-typescript', ], }; export default { roots: ['./projects/'], setupFilesAfterEnv: ['./jest.setup.js', 'jest-fetch-mock'], preset: 'ts-jest', coverageDirectory: 'test-coverage', testMatch: ['**/*.test.[jt]s?(x)'], clearMocks: true, moduleFileExtensions: ['js', 'jsx', 'ts', 'tsx'], testEnvironmentOptions: { exitEarly: true, }, transform: { '^.+\\.(ts|tsx)$': ['ts-jest', { useESM: true }], '^.+\\.(js|jsx)$': ['babel-jest', babelConfig], }, extensionsToTreatAsEsm: ['.ts'], testEnvironment: 'node', moduleDirectories: ['node_modules', 'src'], moduleNameMapper: { '^@jsd-core/data/(.*)$': path.resolve('./projects/jsd-data/src/$1'), '^@jsd-core/utils(.*)$': path.resolve('./projects/jsd-utils/$1'), '^@jsd-core/type(.*)$': path.resolve('./projects/jsd-type/$1'), }, };

setup文件

// jest.setup.js import { JSDOM } from 'jsdom'; import 'jest-localstorage-mock'; const dom = new JSDOM('<!doctype html><html><body></body></html>', { url: 'http://localhost', }); const timeouts = []; afterAll(() => { timeouts.forEach((id) => { clearTimeout(id); }); }); global.window = dom.window; global.document = dom.window.document; global.navigator = dom.window.navigator; global.requestAnimationFrame = (callback) => { const id = setTimeout(callback, 0); timeouts.push(id); return id; };

jest-fetch-mock的使用

在 Jest 环境中模拟 fetch 请求,你可以使用 jest-fetch-mock 库。以下是使用 pnpm 安装和配置 jest-fetch-mock 的步骤:
  1. 安装 jest-fetch-mock: 使用 pnpm 安装 jest-fetch-mock 作为开发依赖:
    1. pnpm add -D jest-fetch-mock
  1. 配置 Jest: 在你的 Jest 配置文件中(例如 jest.config.js 或者在 package.json 中的 Jest 部分),添加 jest-fetch-mock 作为 setupFilesAfterEnv 的一部分:
    1. module.exports = { setupFilesAfterEnv: ['jest-fetch-mock'], };
  1. 在测试中使用 fetch: 一旦配置完成,你就可以在测试中模拟 fetch 调用了。例如:
    1. test('fetches data successfully', async () => { fetch.mockResponseOnce(JSON.stringify({ data: 'mocked data' }), { status: 200 }); const response = await fetch('http://example.com/data'); const data = await response.json(); expect(data).toEqual({ data: 'mocked data' }); });
  1. 模拟不同的响应: 你可以使用 fetch.mockResponsefetch.mockResponseOnce 来模拟不同的响应。例如,模拟一个失败的请求:
    1. fetch.mockReject(new Error('Network error'));
  1. 重置模拟: 在测试之间,你可能需要重置模拟的状态,可以使用 fetch.resetMocks
    1. afterEach(() => { fetch.resetMocks(); });
使用 jest-fetch-mock 可以避免在测试中实际进行 HTTP 请求,使得测试更加稳定和可预测。同时,它也提供了一个简单的方式来模拟 fetch 的行为,使得你可以专注于测试你的代码逻辑而不是网络请求。更多详细信息和高级用法,可以查看 jest-fetch-mock 的官方文档和 GitHub 仓库