React组件内部formatter方法测试失败:如何验证方法已调用?
解决React组件内部方法调用的测试问题
我来帮你搞定这个测试问题~你遇到的TypeError: Cannot read property '_isMockFunction' of undefined错误,核心原因是你在组件实例创建之后才去监听方法,但formatter是在constructor里立刻执行的,这时候不仅监听晚了,还因为实例化后再去spy已经拿不到正确的方法引用了。
正确的测试思路
要验证formatter是否被调用,你需要在组件实例化(也就是shallow渲染)之前就监听组件原型上的方法——因为constructor会在实例创建的瞬间执行,晚一步就赶不上方法的调用时机了。另外还要注意给组件传递必要的menuData props,否则原组件里的data.map会直接报错。
修正后的测试代码
describe.only('SiderMenu.formatter', () => { it('should be called during initialization', () => { // 1. 在渲染组件前,先监听原型上的formatter方法 const formatterSpy = jest.spyOn(SiderMenu.prototype, 'formatter'); // 2. 传递mock的menuData,避免组件内部map报错 const mockMenuData = [{ path: '/test-page' }]; const wrapper = shallow(<SiderMenu menuData={mockMenuData} />); // 3. 断言方法被调用 expect(formatterSpy).toHaveBeenCalled(); // 可选:测试完成后清理spy,避免影响其他用例 formatterSpy.mockRestore(); }); });
为什么你的原代码会失败?
- 你先执行了
shallow(<SiderMenu />),这时候组件的constructor已经跑完了,formatter已经被调用过一次,之后再去spy实例上的方法,不仅监听不到之前的调用,还因为实例化后方法的引用已经发生变化,导致jest找不到对应的mock函数。 - 你没有传递
menuDataprops,原组件里this.formatter(props.menuData)会传入undefined,执行data.map时会直接抛出错误,这也会间接导致spy逻辑失效。
额外测试提示
如果之后你还想验证formatter方法的返回值或参数处理是否正确,可以在spy时用mockImplementation替换原方法,来校验传入的参数或自定义返回结果:
it('should format menu data correctly', () => { const mockMenuData = [{ path: '/sub-menu' }]; const formatterSpy = jest.spyOn(SiderMenu.prototype, 'formatter') .mockImplementation((data) => { // 验证传入的参数是否符合预期 expect(data).toEqual(mockMenuData); // 自定义返回值,也可以调用原方法 return SiderMenu.prototype.formatter(data); }); shallow(<SiderMenu menuData={mockMenuData} />); formatterSpy.mockRestore(); });
内容的提问来源于stack exchange,提问作者geo
相关产品推荐
相关产品推荐

