Skip to content

Instantly share code, notes, and snippets.

@captbaritone
Last active January 17, 2017 17:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save captbaritone/ca8812f30bad478a333b47470398f818 to your computer and use it in GitHub Desktop.
Save captbaritone/ca8812f30bad478a333b47470398f818 to your computer and use it in GitHub Desktop.

Testing React+Redux code

Test "connected" React components

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();
});

Isolate your Redux store

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;

Export your unwarpped React Components

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

Dispatch actions to setup your component's state

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();
    });
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment