Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Unit Test React-Redux Connected Components?

I am using Mocha, Chai, Karma, Sinon, Webpack for Unit tests.

I followed this link to configure my testing environment for React-Redux Code.

How to implement testing + code coverage on React with Karma, Babel, and Webpack

I can successfully test my action and reducers javascript code, but when it comes to testing my components it always throw some error.

import React from 'react'; import TestUtils from 'react/lib/ReactTestUtils'; //I like using the Test Utils, but you can just use the DOM API instead. import chai from 'chai'; // import sinon from 'sinon'; import spies from 'chai-spies';  chai.use(spies);  let should = chai.should()   , expect = chai.expect;  import { PhoneVerification } from '../PhoneVerification';  let fakeStore = {       'isFetching': false,       'usernameSettings': {         'errors': {},         'username': 'sahil',         'isEditable': false       },       'emailSettings': {         'email': '[email protected]',         'isEmailVerified': false,         'isEditable': false       },       'passwordSettings': {         'errors': {},         'password': 'showsomestarz',         'isEditable': false       },       'phoneSettings': {         'isEditable': false,         'errors': {},         'otp': null,         'isOTPSent': false,         'isOTPReSent': false,         'isShowMissedCallNumber': false,         'isShowMissedCallVerificationLink': false,         'missedCallNumber': null,         'timeLeftToVerify': null,         '_verifiedNumber': null,         'timers': [],         'phone': '',         'isPhoneVerified': false       } }  function setup () {     console.log(PhoneVerification);     // PhoneVerification.componentDidMount = chai.spy();     let output = TestUtils.renderIntoDocument(<PhoneVerification {...fakeStore}/>);     return {         output     } }  describe('PhoneVerificationComponent', () => {     it('should render properly', (done) => {         const { output } = setup();         expect(PhoneVerification.prototype.componentDidMount).to.have.been.called;         done();     }) }); 

This following error comes up with above code.

FAILED TESTS:   PhoneVerificationComponent     ✖ should render properly       Chrome 48.0.2564 (Mac OS X 10.11.3)     Error: Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. 

Tried switching from sinon spies to chai-spies.

How should I unit test my React-Redux Connected Components(Smart Components)?

like image 551
Ayushya Avatar asked Feb 01 '16 13:02

Ayushya


People also ask

How do you test connected components in React redux?

import {render, screen} from "@testing-library/react"; import {Provider} from "react-redux"; import {createStore} from "../../app/store"; import {Counter} from "./Counter"; describe('Counter component', () => { test('renders the counter component', () => { render( <Provider store={createStore()}> <Counter /> </Provider ...

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.

How do I test Redux state in jest?

const getName = () => (dispatch) => { const URL = getUrl() fetch(URL, {method: 'GET'}) . then((response) => response. json()) . then(({ data }) => dispatch({ type: 'SAVE_NAME', payload: data.name })) # This action updates the name inside the redux state };


1 Answers

A prettier way to do this, is to export both your plain component, and the component wrapped in connect. The named export would be the component, the default is the wrapped component:

export class Sample extends Component {      render() {         let { verification } = this.props;         return (             <h3>This is my awesome component.</h3>         );     }  }  const select = (state) => {     return {         verification: state.verification     } }  export default connect(select)(Sample); 

In this way you can import normally in your app, but when it comes to testing you can import your named export using import { Sample } from 'component'.

like image 151
Ashwin van Dijk Avatar answered Oct 14 '22 18:10

Ashwin van Dijk