Jest/Enzyme Unit Testing: How to pass store to shallow component that uses redux 4 and react-redux 6 connect function

15,247

shallow and dive doesn't work as expected in react-redux 6, so you may want to downgrade it to react-redux 5.0.7 for it to work.

But if you prefer using react-redux 6, then you might want to use mount instead. So, the above code can be rewritten as follows:

Input.test.js

import React from 'react'
import {Provider} from 'react-redux'
import {mount} from 'enzyme'

import {findByAttr, storeFactory} from '../test/testUtils'
import Input from './Input'

const setup = (initialState={}) => {
  const store = storeFactory(initialState)
  const wrapper = mount(<Provider store={store}><Input /></Provider>)
  console.log(wrapper.debug())
}

setup()

Console

    console.log src/Input.test.js:11
      <Provider store={{...}}>
        <Connect(Input)>
          <Input dispatch={[Function: dispatch]}>
            <div />
          </Input>
        </Connect(Input)>
      </Provider>

And there is another workaround if prefer testing the component as unconnected component, you can still use react-redux 6 and use shallow; code can be rewritten as follows:

Add export keyword to Input

Input.js

import React, { Component } from 'react';
import { connect } from 'react-redux';

export class Input extends Component {
    render(){
        return <div />;
    }
}

const mapStateToProps = (state) => {
    return {};
}

export default connect(mapStateToProps)(Input);

Input.test.js

import React from 'react';
import { shallow } from 'enzyme';

import { findByTestAttr } from '../../../test/testUtils';
import { Input } from './Input';



const setup = (props={}) => {
    const wrapper = shallow(<Input {...props} />);
    console.log(wrapper.debug());

}

Console

<div />

Hope this helps!

Share:
15,247

Related videos on Youtube

Juan
Author by

Juan

I'm a Software Engineer and I'm always enthusiastic about new opportunities. Languages: Javascript Python Frontend: React Angular Typescript Vanilla JS Backend: Node.js Express Flask Mobile: React Native DB: PostgreSQL MongoDB Firebase DB Cloud Services &amp; Deployments: AWS Firebase Docker Terraform Circle CI Data: Apache Airflow Pandas Currently learning: Kubernetes

Updated on June 04, 2022

Comments

  • Juan
    Juan almost 2 years

    I'm doing as usual some unit tests with jest and enzyme for one new project. I used to test components that were connected to redux in this way:

    a) a store generator

    import { createStore } from 'redux';
    
    import rootReducer from '../src/reducers';
    
    export const storeFactory = (initialState) => {
       return createStore(rootReducer, initialState);
    }
    

    which is consumed by the Input.test.js file

    import React from 'react';
    import { shallow } from 'enzyme';
    
    import { findByTestAttr,storeFactory } from '../../../test/testUtils';
    import Input from './Input';
    
    
    
    const setup = (initialState={}) => {
        const store = storeFactory(initialState);
        const wrapper = shallow(
            <Input store={store} />
            ).dive();
        console.log(wrapper.debug());
    
    }
    

    being the example component Input.js:

    import React, { Component } from 'react';
    import { connect } from 'react-redux';
    
    class Input extends Component {
        render(){
            return <div />;
        }
    }
    
    const mapStateToProps = (state) => {
        return {};
    }
    
    export default connect(mapStateToProps)(Input);
    

    My npm package versions are:

     "dependencies": {
        "ajv": "^6.6.2",
        "react": "^16.7.0",
        "react-dom": "^16.7.0",
        "react-redux": "^6.0.0",
        "react-scripts": "2.1.3",
        "redux": "^4.0.1"
      }
    
      "devDependencies": {
        "check-prop-types": "^1.1.2",
        "enzyme": "^3.8.0",
        "enzyme-adapter-react-16": "^1.7.1",
        "jest": "^23.6.0",
        "jest-enzyme": "^7.0.1",
        "prop-types": "^15.6.2"
      }
    

    And that used to work, but I'm getting this message when running the tests on the tests execution report:

    Invariant Violation: Passing redux store in props has been removed and does not do anything. To use a custom Redux store for specific components, create a custom React context with React.createContext(), and pass the context object to React-Redux's Provider and specific components like: . You may also pass a {context : MyContext} option to connect

    I tried to pass the context as a parameter of shallow

    const setup = (initialState={}) => {
        const store = storeFactory(initialState);
        const wrapper = shallow(
            <Input  />, { store }
            );
        console.log(wrapper.debug());
    
    }
    

    But then I get this logged to console

    <ContextConsumer>
            [function bound renderWrappedComponent]
          </ContextConsumer>
    

    and if I try to use then enzyme dive() method I get:

    const setup = (initialState={}) => {
        const store = storeFactory(initialState);
        const wrapper = shallow(
            <Input  />, { store }
            ).dive();
        console.log(wrapper.debug());
    
    }
    

    Test suite failed to run

    TypeError: ShallowWrapper::dive() can only be called on components
    

    Which is the suggested way of doing it now? I know what the message says but before there was no need of wrapping the element into a Provider for jest/enzyme unit tests. Thank you very much!

  • Juan
    Juan about 5 years
    Great my friend. I downgraded and it´s nice to know I can upgrade again xD
  • Sagar Khatri
    Sagar Khatri about 5 years
    @Pranav Can you please explain how can I send store into the Input while using shallow?