Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redux: How to test a connected component?

Tags:

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' });   }); }); 
like image 316
Umair Sarfraz Avatar asked Aug 17 '16 21:08

Umair Sarfraz


People also ask

How does a Redux connected component know when to re render?

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.

What are connected components in React?

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.


1 Answers

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);   }); }); 
like image 88
anoop Avatar answered Sep 29 '22 19:09

anoop