如何为函数式组件中被子组件调用的foo函数编写Jest测试用例
测试Parent组件中foo函数的调用逻辑
要验证Parent组件定义的foo函数,在Child组件的childFun(由View的onLayout触发)中被正确调用,我们可以结合Jest和React测试工具库编写测试用例,具体实现如下:
测试思路
- 渲染Parent组件,确认它将内部
foo函数作为props传递给Child。 - 触发Child组件中View的
onLayout事件,触发childFun进而执行foo。 - 断言
foo函数确实被执行。
测试代码示例
方式一:适配原代码结构(监听console输出)
原代码中foo会执行console.log("hello world"),我们可以通过Jest监听console的log方法来验证调用:
import React from 'react'; import { render, fireEvent } from '@testing-library/react'; import Parent from './Parent'; describe('Parent Component', () => { it('调用Child的onLayout时会触发Parent的foo函数', () => { // 监听console.log并替换实现 const consoleSpy = jest.spyOn(console, 'log').mockImplementation(); // 渲染Parent组件 const { getByText } = render(<Parent />); // 通过子组件文本定位到View元素 const childView = getByText('child views').parentElement; // 触发onLayout事件 fireEvent(childView, new Event('layout')); // 断言console.log被调用,且参数正确 expect(consoleSpy).toHaveBeenCalledWith('hello world'); // 恢复console.log原始实现 consoleSpy.mockRestore(); }); });
方式二:重构代码提升可测试性(推荐)
若不想依赖console输出,可以将foo提取为可外部访问的导出函数,方便直接mock:
修改Parent.js:
export const foo = () => { console.log("hello world"); }; const Parent = () => { return <Child foo={foo} />; }; export default Parent;
对应的测试文件:
import React from 'react'; import { render, fireEvent } from '@testing-library/react'; import Parent, { foo } from './Parent'; // mock导出的foo函数 jest.mock('./Parent', () => { const originalModule = jest.requireActual('./Parent'); return { ...originalModule, foo: jest.fn(), }; }); describe('Parent Component', () => { it('调用Child的onLayout时会触发Parent的foo函数', () => { render(<Parent />); const childView = getByText('child views').parentElement; fireEvent(childView, new Event('layout')); // 直接断言foo被调用一次 expect(foo).toHaveBeenCalledTimes(1); }); });
注意事项
- 若为React Native项目,建议使用
@testing-library/react-native,此时可以用fireEvent.onLayout(childView)简化事件触发。 - 模拟console方法后,务必恢复原始实现,避免干扰其他测试用例。
内容的提问来源于stack exchange,提问作者Ruban Dharmaraj
相关产品推荐
相关产品推荐

