I am using Enzyme
to unit test my React components. I understand that in order to test the raw unconnected component I'd have to just export it and test it (I've done that). I have managed to write a test for the connected component but I am really not sure if this's the right way and also what exactly would I want to test for the connected component.
Container.jsx
import {connect} from 'react-redux'; import Login from './Login.jsx'; import * as loginActions from './login.actions'; const mapStateToProps = state => ({ auth: state.auth }); const mapDispatchToProps = dispatch => ({ loginUser: credentials => dispatch(loginActions.loginUser(credentials)) }); export default connect(mapStateToProps, mapDispatchToProps)(Login);
Container.test.js
import React from 'react'; import {Provider} from 'react-redux'; import {mount, shallow} from 'enzyme'; import {expect} from 'chai'; import LoginContainer from '../../src/login/login.container'; import Login from '../../src/login/Login'; describe('Container Login', () => { it('should render the container component', () => { const storeFake = state => ({ default: () => { }, subscribe: () => { }, dispatch: () => { }, getState: () => ({ ...state }) }); const store = storeFake({ auth: { sport: 'BASKETBALL' } }); const wrapper = mount( <Provider store={store}> <LoginContainer /> </Provider> ); expect(wrapper.find(LoginContainer).length).to.equal(1); const container = wrapper.find(LoginContainer); expect(container.find(Login).length).to.equal(1); expect(container.find(Login).props().auth).to.eql({ sport: 'BASKETBALL' }); }); });
It deduces the changes of your data by running the reducer function you provide, and returns the next state that corresponds to every action dispatched. React Redux then optimizes component rendering and makes sure that each component re-renders only when the data it needs change.
The connect() function connects a React component to a Redux store. It provides its connected component with the pieces of the data it needs from the store, and the functions it can use to dispatch actions to the store.
This is an interesting question.
I usually do import both container and component to do the testing. For container testing I use, redux-mock-store
. Component testing is for testing async functions. For instance in your case, login process is an async function using sinon
stubs. Here is a snippet of the same,
import React from 'react'; import {Provider} from 'react-redux'; import {mount, shallow} from 'enzyme'; import {expect} from 'chai'; import LoginContainer from '../../src/login/login.container'; import Login from '../../src/login/Login'; import configureMockStore from 'redux-mock-store'; import thunk from 'redux-thunk'; import { stub } from 'sinon'; const mockStore = configureMockStore([thunk]); describe('Container Login', () => { let store; beforeEach(() => { store = mockStore({ auth: { sport: 'BASKETBALL', }, }); }); it('should render the container component', () => { const wrapper = mount( <Provider store={store}> <LoginContainer /> </Provider> ); expect(wrapper.find(LoginContainer).length).to.equal(1); const container = wrapper.find(LoginContainer); expect(container.find(Login).length).to.equal(1); expect(container.find(Login).props().auth).to.eql({ sport: 'BASKETBALL' }); }); it('should perform login', () => { const loginStub = stub().withArgs({ username: 'abcd', password: '1234', }); const wrapper = mount(<Login loginUser={loginStub} />); wrapper.find('button').simulate('click'); expect(loginStub.callCount).to.equal(1); }); });
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With