使用Jest Mock AccountSelectionModal时出现警告,如何正确Mock?
你遇到的问题根源很明确:当你用jest.mock('../AccountSelectionModal', () => 'AccountSelectionModal')把组件mock成字符串时,React会把它当作自定义HTML元素而非React组件来处理。这就导致所有传给它的props(比如事件处理函数、自定义业务属性)都会被当成未知的DOM属性,进而触发那些恼人的警告。
下面是几种正确的mock方式,能彻底解决这个问题:
1. Mock为接收所有props的简单React函数组件
直接创建一个函数组件来接收并传递所有props,React会正确识别这些props属于组件属性而非DOM属性,不会再抛出警告:
jest.mock('../AccountSelectionModal', () => ({ __esModule: true, // 如果你的组件是ES模块导出(default export),需要加上这个 default: (props) => ( <div data-testid="mock-account-selection-modal" {...props} /> ), }));
这里我们给mock组件加了data-testid,方便后续在测试中定位它,验证是否正确渲染或者读取它的props。
2. 使用jest.fn()创建可断言的Mock组件
如果需要验证父组件是否正确传递了props给Modal,或者断言Modal是否被渲染,可以用jest.fn()来创建mock组件,这样能轻松获取调用记录:
// 先定义一个mock组件函数 const MockAccountSelectionModal = jest.fn((props) => ( <div data-testid="mock-account-modal" {...props} /> )); // 替换原组件 jest.mock('../AccountSelectionModal', () => ({ __esModule: true, default: MockAccountSelectionModal, })); // 在测试用例中进行断言 test('passes correct props to AccountSelectionModal', () => { const wrapper = mount(<AccountSelection {...accountSelectionComponentParams} />); // 断言组件被渲染,且接收了预期的props expect(MockAccountSelectionModal).toHaveBeenCalledWith( expect.objectContaining({ onClose: expect.any(Function), accounts: accountSelectionComponentParams.accounts, }), expect.anything() // 忽略第二个参数(React的上下文等) ); });
3. 针对Redux连接组件的额外说明
因为你的AccountSelectionModal是Redux连接组件(connected component),mock时完全不需要关心它的内部逻辑或store依赖——我们的目标是隔离父组件的测试,所以只需要让mock组件能接收props并正常渲染即可,不需要连接到任何store。
为什么之前的方式不行?
当你返回字符串'AccountSelectionModal'时,React会把它解析成<accountselectionmodal>这样的HTML标签(注意自动转成小写),这就是你看到"大小写错误"警告的原因。同时,所有React组件特有的props(比如onClose、自定义业务属性)对于HTML标签来说都是未知属性,自然会触发"未知事件处理属性"、"未知DOM属性"的警告。
内容的提问来源于stack exchange,提问作者dragonfly

