Enzyme mount未重新渲染props更新组件,Jest单元测试断言失败问题
问题原因
你的断言执行时机早于异步请求的回调执行:
你模拟的request.fetch返回的是异步Promise,输入完三个字段触发请求后,Promise的resolve回调还没进入执行队列,setState更新duplicateRecords的逻辑还没运行,此时执行断言时组件的duplicateRecords还是空数组,所以判断组件未渲染。而控制台打印的内容是断言执行完成后,Promise回调触发、组件重渲染才输出的,因此会出现你看到的「组件render执行了但断言失败」的现象。
你主动调用setState是同步操作,state更新后立即触发组件重渲染,所以断言可以拿到正确结果。
解决方法
- 将测试用例改为异步函数,等待所有微任务执行完成后再执行断言
- 手动调用
wrapper.update()同步Enzyme wrapper的渲染快照 - 检查断言中的组件名是否和实际渲染的组件名一致
修改后的测试代码如下:
// 先导入你实际渲染的组件 import DuplicateRecordsFinder from './duplicate_records_finder' test("it should display duplicate records when person already exists", async () => { // 替换为你的测试用模拟返回数据 const mockDuplicateRecords = [ { id: 1, first_name: "First", last_name: "Last", date_of_birth: "08-13-1990" } ] // 简化mock写法,直接返回resolved状态的Promise request.fetch = jest.fn().mockResolvedValue(mockDuplicateRecords) // 输入三个字段 wrapper.find("input[name='first_name']") .simulate("change", { target: { value: "First", name: "first_name" } }); wrapper.find("input[name='last_name']") .simulate("change", { target: { value: "Last", name: "last_name" } }); wrapper.find("input[name='date_of_birth']") .simulate("change", { target: { value: "08-13-1990", name: "date_of_birth" } }); // 等待所有微任务(包括fetch的回调)执行完成 await Promise.resolve(); // 同步Enzyme wrapper的渲染状态 wrapper.update(); // 确认接口被正确调用(可选校验) expect(request.fetch).toHaveBeenCalled(); // 断言组件已渲染,注意组件名要和实际渲染的组件完全一致 expect(wrapper.find(DuplicateRecordsFinder).exists()).toBe(true); })
补充说明
如果项目中已经安装了flush-promises工具包,也可以用await flushPromises()替代await Promise.resolve(),语义更清晰。
内容的提问来源于stack exchange,提问作者Chetan Gawai
相关产品推荐
相关产品推荐

