如何Mock返回JSX Element的函数?Jest mock未触发问题
问题原因
你的断言失败有两个核心原因:
- 仅调用返回JSX的函数不会触发子组件执行:JSX本质是
React.createElement(组件, props)的语法糖,调用myFunction(someProps)只会生成一个描述UI结构的普通JavaScript对象,不会实际执行MyElement的组件逻辑,你写在Mock组件里的mockFn自然不会被触发。 - Mock配置存在匹配错误:
- 原业务代码中导出、使用的子组件名为
MyElement,你Mock返回的对象里键名写成了MyComponent,名称不匹配导致Mock根本没有被正确引用 - 你贴出的
jest.mock路径字符串缺少闭合单引号,属于语法错误(如果不是粘贴代码时漏写需要修正)
- 原业务代码中导出、使用的子组件名为
解决方案
推荐优先使用第一种方案,完全不需要引入渲染逻辑,也不需要Mock组件,最轻量也最稳定:
方案1:直接解析返回的JSX元素(推荐)
不需要MockMyElement,直接读取myFunction返回的React元素对象做断言即可,完全不会触发MyElement的内部逻辑:
import { MyElement } from '.../path-to-my-component/MyElement'; import myFunction from './myFunction'; test('返回的MyElement携带正确props', () => { const returnedElement = myFunction(someProps); // 校验返回的元素确实是MyElement expect(returnedElement.type).toBe(MyElement); // 直接读取元素props做断言 expect(returnedElement.props).toEqual(expectedNewProps); })
方案2:通过渲染触发Mock校验
如果你一定要用Mock+渲染的方式校验,先修正Mock配置,再实际渲染返回的JSX即可:
- 先修正Mock配置,确保路径、组件名和原模块完全一致:
const mockFn = jest.fn(); // 注意路径必须和myFunction.jsx中导入MyElement的路径完全一致 jest.mock('.../path-to-my-component/MyElement', () => ({ // 键名必须和原模块导出的组件名完全一致 MyElement: (props) => { mockFn(props) return 'my-element' } }))
注意:Jest会自动把
jest.mock调用提升到文件顶部执行,工厂函数中引用的外部变量名必须以mock开头,你定义的mockFn符合该规则,无需额外调整。
- 调用myFunction拿到JSX后,用测试渲染工具实际渲染组件,才会触发Mock组件执行:
import { render } from '@testing-library/react'; import myFunction from './myFunction'; test('返回的MyElement携带正确props', () => { const returnedElement = myFunction(someProps); // 实际渲染返回的JSX,才会执行MyElement的Mock逻辑 render(returnedElement); expect(mockFn).toHaveBeenCalledTimes(1); expect(mockFn).toHaveBeenCalledWith(expectedNewProps); })
内容的提问来源于stack exchange,提问作者Dmitriy Zhiganov
相关产品推荐
相关产品推荐

