React Jest测试遇400状态码报错:axios-mock-adapter问题排查
问题:Jest测试axios 400状态码时抛出错误导致测试失败
我正在学习React中用Jest做单元测试,需要验证API返回200和400状态码的场景。200状态的测试用例能正常通过,但400状态的用例会抛出「Request failed with status code 400」错误,导致测试失败。我已经将测试用例分组,用axios-mock-adapter模拟axios的get方法,想请教问题原因及解决办法,相关代码如下:
UserService.test.ts
import { ACCOUNT_SETTINGS } from '../../core/constants/apiEndpoints' import mockServiceInstance from '../__mocks__/MockService' import { fetchUsersMockData, userClaimsTreeMockData } from "../__mocks__/UserServiceMockData"; import axios from "axios"; import MockAdapter from "axios-mock-adapter"; afterEach(() => { jest.clearAllMocks() }); const mock = new MockAdapter(axios); // roles/list?PageIndex=0&PageSize=3 describe('fetchAllUsers method', () => { let url : string = `${ACCOUNT_SETTINGS.PAGED_LIST}?PageIndex=${0}&PageSize=${3}`; it("get is succesfull", async () => { const mockData = { result: fetchUsersMockData, error: null, isSuccessful: true } mock.onGet(url).reply(200, mockData); const { data } = await axios.get(url) expect(data.result).toStrictEqual(fetchUsersMockData); }) it("get has error", async () => { mock.onGet(url).reply(400); const { status} = await axios.get(url) // 这里报错 }) })
示例Mock数据
fetchUsersMockData = { pageIndex: 0, pageSize: 3, totalCount: 8, totalPages: 1, items: [ { id: uuidv4(), username: "adminuser@test.com.tr", name: "Scot", surname: "Lawson", email: "adminuser@test.com.tr", phoneNumber: "03212342345", isActive: true, isLocked: false, timeZone: "Europe/Istanbul" } ] }
问题原因
axios默认会把4xx、5xx这类错误状态码的请求抛出异常,而不是正常返回响应对象。所以当你模拟400状态码时,axios.get(url)会直接抛出错误,而不是返回包含status的响应,这就导致测试报错。
解决办法
方法1:捕获错误并断言响应状态码
修改400的测试用例,用try/catch捕获axios抛出的错误,然后断言错误对象里的响应状态码:
it("get has error", async () => { mock.onGet(url).reply(400); try { await axios.get(url); // 如果没抛出错误,手动让测试失败 expect(true).toBe(false); } catch (error) { // 可根据项目类型用AxiosError做类型断言,这里用any简化 expect((error as any).response.status).toBe(400); } })
方法2:配置axios不抛出错误(可选)
可以在请求时设置validateStatus选项,让axios对所有状态码都不抛出错误,这样就能正常拿到响应对象:
it("get has error", async () => { mock.onGet(url).reply(400); const { status} = await axios.get(url, { validateStatus: () => true // 对所有状态码都视为成功 }) expect(status).toBe(400); })
额外建议:重置mock适配器
你的afterEach里只清空了Jest的mock,但没有重置axios-mock-adapter的mock,容易导致测试用例互相影响,建议加上:
afterEach(() => { jest.clearAllMocks(); mock.reset(); // 重置mock适配器,清除之前的模拟配置 });
内容的提问来源于stack exchange,提问作者Emre Sert
相关产品推荐
相关产品推荐

