如何用Jest+Enzyme测试路由匹配参数?含React+TS组件h2测试
Great question! Testing route match params with Jest, Enzyme, TypeScript, and React is straightforward once you know how to mock or simulate the route context. Let’s walk through exactly how to test your component that uses match.params.id, including verifying the <h2> element exists.
1. First, Confirm Your Dependencies
Make sure you have these dev dependencies installed (adjust the adapter version to match your React version):
npm install --save-dev jest @types/jest ts-jest enzyme @types/enzyme enzyme-adapter-react-16 react-router-dom @types/react-router-dom
Also, ensure your tsconfig.json and Jest config (like jest.config.js) are set up to handle TypeScript correctly.
2. Mock the Route match Object (Simplest Approach)
Your component receives the match prop from React Router, so you don’t need to spin up a full router in tests—just mock the match object directly.
Example Component (based on your source)
Let’s assume your component looks something like this (typed for TypeScript):
import React from 'react'; import { RouteComponentProps } from 'react-router-dom'; // Define props with route params type interface ItemDetailsProps extends RouteComponentProps<{ id: string }> {} export const ItemDetails: React.FC<ItemDetailsProps> = ({ match }) => { return ( <div className="item-details"> <h2>Item ID: {match.params.id}</h2> {/* Other component content */} </div> ); };
Test Code
Create a test file ItemDetails.test.tsx:
import React from 'react'; import { shallow } from 'enzyme'; import { ItemDetails } from './ItemDetails'; import { RouteComponentProps } from 'react-router-dom'; describe('ItemDetails Component', () => { it('renders the <h2> element with the correct ID from match.params', () => { // Mock the match object with a sample ID const mockMatch: RouteComponentProps<{ id: string }>['match'] = { params: { id: '789' }, isExact: true, path: '/items/:id', url: '/items/789' }; // Shallow render the component with our mocked match prop const wrapper = shallow(<ItemDetails match={mockMatch} />); // Verify the <h2> exists expect(wrapper.find('h2').exists()).toBe(true); // Optional: Verify the <h2> displays the correct ID text expect(wrapper.find('h2').text()).toBe('Item ID: 789'); }); });
Key Notes:
- Shallow Rendering: We use
shallowhere because we only care about the component itself, not its children. Usemountif you need to test deeper component interactions. - Type Safety: The mock
matchis typed to matchRouteComponentProps['match']so TypeScript doesn’t throw errors. - No Full Router Needed: Mocking the
matchprop is faster and simpler than spinning up a router for basic param testing.
3. Alternative: Test with a Real Router (If Needed)
If you want to simulate actual route navigation (e.g., testing how the component loads when navigating to /items/123), use MemoryRouter from react-router-dom:
import React from 'react'; import { mount } from 'enzyme'; import { MemoryRouter, Route } from 'react-router-dom'; import { ItemDetails } from './ItemDetails'; it('renders correctly when navigated to with an ID', () => { const wrapper = mount( <MemoryRouter initialEntries={['/items/123']}> <Route path="/items/:id" component={ItemDetails} /> </MemoryRouter> ); // Check that the <h2> exists and shows the right ID expect(wrapper.find('h2').exists()).toBe(true); expect(wrapper.find('h2').text()).toBe('Item ID: 123'); });
This approach is useful if your component relies on other router-related props (like location or history), but for just testing match.params, the mock approach is preferred.
内容的提问来源于stack exchange,提问作者vanegeek

