React单元测试中无法mock子组件ProjectTeam的问题求助
核心原因
jest.mock调用位置错误。Jest的模块模拟存在全局提升机制,所有jest.mock调用会被自动提升到测试文件最顶部,优先于所有import语句执行。放在beforeEach等运行时钩子内部的jest.mock不会触发模块替换,此时子组件已经完成导入,会保留原有逻辑。
修正方案
- 将
jest.mock调用从beforeEach中移除,放在测试文件的顶级作用域,建议位置为所有import语句之后。 - 如果需要验证子组件的入参,可将模拟组件改为
jest.fn包装的函数组件,方便后续断言调用参数。
修正后测试代码示例
import React from 'react'; import configureMockStore from 'redux-mock-store'; import { Provider } from 'react-redux'; import { render } from '@testing-library/react'; import { I18nextProvider } from 'react-i18next'; import { generateProject } from '../../testing/generators/project'; import { ProjectOverview } from './component'; import { ProjectTeam } from '../../assignment/project-team/component'; import { NGStateProvider } from '../../react/providers/route-provider/component'; import { testAngularRouter } from '../../testing/testAngularRouter'; import { DefaultProjectCollection, DefaultUtilizationCollection } from '../store/model'; import { DefaultApaActionCollection } from '../../apa/model'; import i18n from '../../testing/i18n'; import thunk from 'redux-thunk'; // 顶级作用域调用mock,会自动提升执行 jest.mock('../../assignment/project-team/component', () => ({ ProjectTeam: jest.fn(() => <div data-testid="project-team-mock" />) })); describe('ProjectOverview', () => { let mockStore = null; const project = generateProject(); beforeEach(() => { mockStore = configureMockStore([thunk])({ projects: { DefaultProjectCollection, ...{ entities: { [project.id]: project } } }, toolUtilizations: DefaultUtilizationCollection, apaActions: DefaultApaActionCollection, }); // 每次测试前清空mock调用记录,避免互相影响 (ProjectTeam as jest.Mock).mockClear(); }); test('renders correctly', () => { const { asFragment } = render( <NGStateProvider router={testAngularRouter}> <Provider store={mockStore}> <I18nextProvider i18n={i18n}> <ProjectOverview projectId={project.id} /> </I18nextProvider> </Provider> </NGStateProvider>, ); expect(asFragment()).toMatchSnapshot(); // 可选:验证子组件接收的参数正确 expect(ProjectTeam).toHaveBeenCalledWith({ projectId: project.id }, expect.anything()); }); });
补充说明
如果项目使用ESM模块规范,需要使用jest.unstable_mockModule配合动态import语法实现模拟,CommonJS规范的项目直接使用上述写法即可生效。
内容的提问来源于stack exchange,提问作者Alex A.
相关产品推荐
相关产品推荐

