如何用Jest和Enzyme测试集成Redux Store的React App.js组件
Got it, let's walk through how to test your Redux-connected App component with Enzyme. Here are two reliable approaches you can use, along with step-by-step code examples:
First, make sure you have the necessary packages installed. Depending on your React version, install the matching Enzyme adapter, plus tools for mocking Redux if needed:
# For React 16.x npm install --save-dev enzyme enzyme-adapter-react-16 redux-mock-store # For React 17+, use this adapter instead npm install --save-dev enzyme @wojtekmaj/enzyme-adapter-react-17 redux-mock-store
This method simulates the real app environment by wrapping your component in React Redux's Provider and passing a test store. It's great for verifying that the component correctly interacts with Redux state and actions.
Here's what your App.test.js would look like:
import React from 'react'; import { mount } from 'enzyme'; import { Provider } from 'react-redux'; import configureStore from 'redux-mock-store'; import App from './App'; // Initialize a mock Redux store const mockStore = configureStore([]); describe('Connected App Component', () => { let store; let wrapper; beforeEach(() => { // Set up test state that matches what your mapStateToProps expects store = mockStore({ data: [] // Replace with test-specific state data }); // Mount the component wrapped in Provider wrapper = mount( <Provider store={store}> <App /> </Provider> ); }); it('renders the header and "todos" title correctly', () => { expect(wrapper.find('.header')).toHaveLength(1); expect(wrapper.find('h1').text()).toBe('todos'); }); // Example: Test if the component dispatches the right action (if you add interactive elements later) it('dispatches the correct action when an event triggers', () => { // If you add a button that triggers an action, simulate the click: // wrapper.find('button').simulate('click'); // const actions = store.getActions(); // expect(actions[0].type).toBe('YOUR_ACTION_TYPE'); }); });
Since connect() returns a higher-order component, it's often better to test the raw App component directly—this keeps your tests focused on the component's own logic, not Redux's connection.
First, update your App.js to export the unconnected component:
// Export the base component for testing export class App extends Component { render() { return ( <header className="header"> <h1>todos</h1> </header> ); } } function mapStateToProps(state) { return { data: state.data }; } function mapDispatchToProps(dispatch) { return bindActionCreators(ActionCreators, dispatch); } // Export the connected component as default for your app export default connect(mapStateToProps, mapDispatchToProps)(App);
Now write tests for the unconnected component in App.test.js:
import React from 'react'; import { shallow } from 'enzyme'; import { App } from './App'; // Import the unconnected base component describe('Unconnected App Component', () => { let wrapper; beforeEach(() => { // Pass mock props that mimic what Redux would provide wrapper = shallow(<App data={[]} />); }); it('renders the header and "todos" title correctly', () => { expect(wrapper.find('.header')).toHaveLength(1); expect(wrapper.find('h1').text()).toBe('todos'); }); // Example: Test if the component uses props correctly (if you add logic later) it('responds to prop changes as expected', () => { // Update props and check if the component re-renders appropriately wrapper.setProps({ data: ['test todo'] }); // Add assertions based on your component's logic }); // Example: Test if dispatch props are called (if you add interactive elements) it('triggers the correct prop method when an event occurs', () => { const mockAction = jest.fn(); const wrapper = shallow(<App yourAction={mockAction} />); // Simulate an event like a button click: // wrapper.find('button').simulate('click'); // expect(mockAction).toHaveBeenCalled(); }); });
Quick Notes:
- Use
shallowfor testing the component in isolation (no child components rendered) - Use
mountwhen you need to test the full component tree or Redux integration - Approach 2 is preferred for unit tests because it isolates your component from Redux, making tests faster and easier to debug
内容的提问来源于stack exchange,提问作者test

