如何解决Jest中Mock模块时的Node模块依赖解析问题?
Let's break down why your __mocks__ setup isn't working when importing from ../A (the package index) and walk through how to fix it.
The Root Issue
Jest's mock resolution logic relies on matching the exact import path your code uses. When you import ../A (which resolves to A/index.ts under the hood), Jest expects a mock structure that mirrors the real package's setup at the right location. Your initial shared __mocks__/A/ folder wasn't being picked up because:
- For directory/package imports, Jest defaults to looking for a mock directory at the sibling level of the real package folder, not nested inside a top-level shared
__mocks__(unless you explicitly configure it otherwise). - Your mock didn't properly mirror the real package's entry point (the
index.tsinA/).
Step-by-Step Solution
1. Fix the Mock Directory Structure
Instead of a shared __mocks__ folder with both A/ and B/ inside, create a __mocks__ directory directly next to your A/ folder. Inside it, mirror the A/ package structure to target the entry point:
your-project/ ├── A/ │ ├── A.tsx │ └── index.ts ├── __mocks__/ │ └── A/ │ └── index.ts # Mocks the A package's index entry ├── B/ │ ├── B.tsx │ └── ... └── test.tsx
2. Write the Mock for A's Index File
In __mocks__/A/index.ts, export your mocked A component to match what your test needs:
// __mocks__/A/index.ts import React from 'react'; export const A = () => <div id='A' />;
3. Update Your Test File
Keep your test's jest.mock call pointing to the same package path your component uses:
// test.tsx import React from 'react'; import { render } from '@testing-library/react'; import B from '../B/B'; jest.mock('../A'); // Now resolves to __mocks__/A/index.ts automatically describe('B Component', () => { it('renders the mocked A component', () => { const { getByTestId } = render(<B />); expect(getByTestId('A')).toBeInTheDocument(); }); });
4. Optional: Use a Shared mocks Folder (With Config)
If you prefer to keep all mocks in a single top-level __mocks__ folder, add a mapping to your jest.config.js to explicitly tell Jest where to find the mock for ../A:
// jest.config.js module.exports = { // ... other Jest config moduleNameMapper: { '^../A$': '<rootDir>/__mocks__/A/index.ts', }, };
This bypasses Jest's default sibling-directory check and maps the import path directly to your shared mock.
Why Your Second Setup Worked
When you changed the import to ../A/A.tsx and created A/__mocks__/A.tsx, Jest's default resolution kicked in: it looks for __mocks__ inside the same directory as the individual file being mocked, which aligns with how Jest handles single-file imports.
内容的提问来源于stack exchange,提问作者Dmitry McLygin

