When testing React components which have been connected to a Redux store via
react-redux
's connect()
, you can pass your store directly to the wrapped
component like so:
it('renders a "happy path" state to snapshot', () => {
const store = getStore();
const myWrappedComponent = renderer.create(
<MyWrappedComponent store={store} />
).toJSON();
expect(myWrappedComponent).toMatchSnapshot();
});
Note: If your component has child components which are also connected, this
approach will not propagate the store into those children. In this case you
will need to use an actual <Provider>
component.
import {Provider} from 'react-redux';
test('renders a "happy path" state to snapshot', () => {
const store = getStore();
const myWrappedComponent = renderer.create(
<Provider store={store}>
<MyWrappedComponent store={store} />
</Provider>
).toJSON();
expect(myWrappedComponent).toMatchSnapshot();
});
It can be useful to utilize your Redux store to test "connected" React components. This means you may want to have multiple instances of your store. To achieve this, create a module that exports a factory function which returns a new store:
import { createStore } from 'redux';
import rootReducer from './reducers/index';
// Exporting the store as a factory function, makes it easy to have our tests
// generate multiple distinct stores and avoid shared state.
const getStore = () => {
return createStore(
rootReducer
);
};
export default getStore;
In your actual app, this function will only get executed once, but in tests you can execute it before each test so that you can setup your test state from scratch in each test.
In tests it can be useful to export your React component before you "connect" it to your Redux store. To do this, simply export the unwrapped component as a named propery of your module, leaving the wrapped component as the default export.
// my_component.js
export const MyComponent = (props) => <h1>{props.title}</h1>;
export default connect((state) => state)(MyComponent);
// my_component.test.js
import {MyComponent} from './my_component'; // Unwrapped component
import MyComponent from './my_component'; // Wrapped component
You may want to test or snapshot your component in a specific state. If that state is complex, it may be easier to dispatch some number of Redux actions to setup the given state. This can be especially valuable when combined with JSON fixtures of sample API response data.
import React from 'react';
import {Provider} from 'react-redux';
import renderer from 'react-test-renderer';
import LeadsList from './leads_list';
import getStore from '../store';
import {receivedLeads} from '../actions/app_actions';
import {loadJSONFixture} from '../../../../js/tests/utils';
const apiResponse = loadJSONFixture('static/jsx/poly/leads/fixtures/sample_api_response.json');
describe('LeadRow component', () => {
let store;
beforeEach(() => {
store = getStore();
});
it('renders a "happy path" state to snapshot', () => {
store.dispatch(receivedLeads(apiResponse));
const leadsList = renderer.create(
<Provider store={store}>
<LeadsList />
</Provider>
).toJSON();
expect(leadsList).toMatchSnapshot();
});
});