React测试Mock Axios fetch请求 测试套件无测试用例报错排查
问题原因
你遇到的Your test suite must contain at least one test报错,直接原因是describe测试块内仅配置了MSW服务的生命周期钩子(启动/重置/关闭),没有编写任何实际的测试用例(test/it块),测试运行器找不到可执行的断言逻辑,就会抛出该错误。
除此之外你的代码还有几个会导致测试无法正常运行的问题:
ListData组件缺少React、axios的导入,没有默认导出,也没有返回任何可渲染的JSX,本身无法正常挂载- MSW的请求匹配规则把query参数硬编码在URL字符串中,容易因为参数编码、顺序问题导致匹配失效
- 没有引入React组件测试工具完成组件渲染,也没有处理异步请求的等待逻辑,就算写了用例也会拿不到更新后的组件状态
正确实现方案
第一步:补全可正常运行的组件代码
先修复ListData.js的问题,保证组件本身可渲染、可导出:
import { useState, useEffect } from 'react'; import axios from 'axios'; const ListData = () => { const [data, setData] = useState([]); const [searchValue, setSearchValue] = useState(""); const [error, setError] = useState(null); useEffect(() => { axios .get("https://images-api.nasa.gov/search", { params: { media_type: 'image' } // 抽离query参数,避免硬编码拼接 }) .then((response) => { setData(response.data); }) .catch((err) => { console.log(err); setError(err); }); }, []); if (error) return <div>加载失败</div>; return ( <div> <input value={searchValue} onChange={(e) => setSearchValue(e.target.value)} placeholder="搜索" /> <div data-testid="api-content">{JSON.stringify(data)}</div> </div> ); }; export default ListData;
第二步:补全测试逻辑
使用React Testing Library完成组件渲染、异步等待和断言,修复MSW匹配规则,补充缺失的测试用例:
提前安装依赖:
npm i -D @testing-library/react @testing-library/jest-dom,并在Jest配置文件中引入@testing-library/jest-dom以支持DOM断言
import { rest } from "msw"; import { setupServer } from "msw/node"; import { render, screen, waitFor } from "@testing-library/react"; import ListData from "./Components/ListData"; const mockSuccessData = { collection: { items: [] } }; // 配置MSW服务,仅匹配路径,query参数通过请求对象校验 const server = setupServer( rest.get( "https://images-api.nasa.gov/search", (req, res, ctx) => { const mediaType = req.url.searchParams.get('media_type'); if (mediaType === 'image') { return res(ctx.status(200), ctx.json(mockSuccessData)); } return res(ctx.status(400)); } ) ); describe("ListData", () => { beforeAll(() => server.listen()); afterEach(() => server.resetHandlers()); afterAll(() => server.close()); // 正常请求场景测试用例 test("组件挂载后自动拉取图片接口并渲染返回数据", async () => { render(<ListData />); // 等待异步请求完成、组件状态更新后再断言 await waitFor(() => { expect(screen.getByTestId('api-content')).toHaveTextContent( JSON.stringify(mockSuccessData) ); }); }); // 异常场景测试用例 test("接口请求失败时展示错误提示", async () => { // 临时覆写接口返回,模拟服务端错误 server.use( rest.get("https://images-api.nasa.gov/search", (_, res, ctx) => { return res(ctx.status(500)); }) ); render(<ListData />); await waitFor(() => { expect(screen.getByText('加载失败')).toBeInTheDocument(); }); }); });
关键注意点
- 测试异步逻辑时,必须使用
waitFor或者Testing Library提供的findBy*系列查询方法,等待请求完成、组件重渲染后再做断言,否则会拿到初始状态的渲染结果导致断言失败 - MSW匹配带query参数的请求时,不要把query字符串拼在匹配URL里,通过
req.url.searchParams读取校验参数即可,避免出现匹配不到mock请求的问题 - 每个测试用例结束后
server.resetHandlers()会重置为默认的mock规则,不会影响其他用例的逻辑
内容的提问来源于stack exchange,提问作者Teshie Ethiopia
相关产品推荐
相关产品推荐

