Reputation: 83
I've been struggling for a few days writing a jest test for a React-Redux app. I'm testing one page that simply displays some account information. The page was written using a connected component with a container class. I've successfully tested if the page renders, but now I'm trying to test that it displays the correct information. It seems my main issue is troubles creating a mock store. However, I also wonder if I'm even writing the test correctly, as a lot of websites have recommended testing the mapStateToProps function (though I can't figure out how). If anyone has any advice, I'd really appreciate it!
Here is the container class:
import {connect} from "react-redux";
import Account from "../components/Account";
const mapStateToProps = (state) => {
return {
email: state.user.email || "",
firstName: state.user.firstName || "",
lastName: state.user.lastName || "",
joined: new Date(state.user.joined).toLocaleDateString(),
};
};
const AccountContainer = connect (mapStateToProps)(Account);
export default AccountContainer;
Here is my test:
import React from 'react';
import {shallow, mount} from 'enzyme';
import AccountContainer, {Account} from '../authed/components/Account';
import configureStore from 'redux-mock-store';
import {Provider} from 'react-redux';
import {createStore} from 'redux';
import * as Enzyme from 'enzyme';
import ReactSixteenAdapter from 'enzyme-adapter-react-16';
Enzyme.configure({ adapter: new ReactSixteenAdapter() });
describe('Account Page Test', () => {
const initialState = {
email: "[email protected]",
firstName: "John",
lastName: "Doe",
joined: new Date().toLocaleDateString(),
}
const mockStore = configureStore()
let store, container
beforeEach(() => {
store = mockStore(initialState)
container = shallow(<AccountContainer store={store}/>)
})
test('the connected component gets rendered', () => {
expect(container.length).toEqual(1)
});
test('the prop matches with initialState', () => {
expect(container.prop('email')).toEqual(initialState.email),
expect(container.prop('firstName')).toEqual(initialState.firstName),
expect(container.prop('lastName')).toEqual(initialState.lastName),
expect(container.prop('joined')).toEqual(initialState.joined),
});
});
TL;DR: I'm new to React/Redux and Jest and need help figuring out what's wrong with my test and knowing if I'm testing the right thing
Upvotes: 2
Views: 1676
Reputation: 5944
Official docs recommend to test not connected component, so in your case, you can test that Account
component just render passed props correctly. It's much simpler then mock the store.
I.e. if Account
is just a static container, you can test that it matches the snapshot:
import {Account} from '../authed/components/Account';
import * as Enzyme from 'enzyme';
import renderer from 'react-test-renderer';
import ReactSixteenAdapter from 'enzyme-adapter-react-16';
Enzyme.configure({ adapter: new ReactSixteenAdapter() });
describe('Account Page Test', () => {
const initialState = {
email: "[email protected]",
firstName: "John",
lastName: "Doe",
joined: "7/12/2018",
}
test('the prop matches with initialState', () => {
const tree = renderer
.create(<Account {...initialState}>)
.toJSON();
expect(tree).toMatchSnapshot();
});
});
Upvotes: 1
Reputation: 11544
I will recommend the same as @Alex. To test the component separately. The approach you have taken isn't really Unit testing.
However, if you want to stick to your approach. My guess is to wrap your container with provider
and pass the store to it will work. And you have to replace shallow
rendering with mount
import React from 'react';
import {shallow, mount} from 'enzyme';
import AccountContainer, {Account} from '../authed/components/Account';
import configureStore from 'redux-mock-store';
import {Provider} from 'react-redux';
import {createStore} from 'redux';
import * as Enzyme from 'enzyme';
import ReactSixteenAdapter from 'enzyme-adapter-react-16';
Enzyme.configure({ adapter: new ReactSixteenAdapter() });
describe('Account Page Test', () => {
const initialState = {
email: "[email protected]",
firstName: "John",
lastName: "Doe",
joined: new Date().toLocaleDateString(),
}
const mockStore = configureStore()
let store, container
beforeEach(() => {
store = mockStore(initialState)
container = mount(<Provider store={store}>
<AccountContainer />
</Provider>)
})
test('the connected component gets rendered', () => {
expect(container.length).toEqual(1)
});
test('the prop matches with initialState', () => {
expect(container.prop('email')).toEqual(initialState.email),
expect(container.prop('firstName')).toEqual(initialState.firstName),
expect(container.prop('lastName')).toEqual(initialState.lastName),
expect(container.prop('joined')).toEqual(initialState.joined),
});
});
Upvotes: 3