using enzyme.mount().setProps with a react-redux Provider

You should only be calling setProps on the wrapped component or parent.

A good rule of thumb is your test should only be testing a single component (the parent), so setting props on children is not permitted with enzyme.

https://github.com/airbnb/enzyme/blob/master/docs/api/ShallowWrapper/setProps.md#setpropsnextprops--self

If you have child components further down that we need to satisfy store dependencies for (via Provider and context), then that is fine, but those child components should really have their own isolated tests.

That is where you'd be encouraged to write a test for a change on setProps.

If you find yourself writing tests for a container or connector, you would really only want to verify that the child component is receiving the correct props and or state. For example:

import { createMockStore } from 'mocks'
import { shallwo } from 'enzyme'
// this component exports the redux connection
import Container from '../container'

const state = { foo: 'bar' }

let wrapper
let wrapped
let store

beforeEach(() => {
  store = createMockStore(state)
  wrapper = shallow(<Container store={store} />)
  wrapped = wrapper.find('MyChildComponent')
})

it('props.foo', () => {
  const expected = 'bar'
  const actual = wrapped.prop('foo')
  expect(expected).toEqual(actual)
})

One other tip is that it helps to understand the difference between shallow and mount so you aren't needlessly mocking dependencies for children in a test, the top answer here is a good read:

When should you use render and shallow in Enzyme / React tests?


Another approach will be to use wrappingComponent.

For example, let say this is your provider

const ExampleProvider = ({ children }) => (
      <Provider store={store}>
        {children}
      </Provider>
    );

and then initialize wrapper as follows

wrapper = mount(<Component />, { wrappingComponent: ExampleProvider});

And then in test cases, you should be able to call wrapper.setProps directly.


Here's an approach using the setProps

import { Provider } from 'react-redux';


const renderComponent = properties => mount(
  React.createElement(
    props => (
      <Provider store={store}>
        <IntlProvider locale="en" defaultLocale="en" messages={messages}>
      <Router>
        <MyComponent {...props} />
      </Router>

      </Provider>
    ),
    properties))

Then in your test

it('should set some props', () => {
   const renderedComponent = renderComponent(props);
   renderedComponent.setProps({ /* some props */ } });

  expect(true).toBe(true);
})

I had the same issue after wrapping my component in a Provider. What I did is, I used setProps on children instead of a component itself.

This is the example of my component in test suite:

 let component, connectedComponent; 
 component = () => {
 store = configureMockStore()(myStore);  
 connectedComponent = mount(
     <Provider >
       <MyComponent store={store} params={{xyz: 123}} />
     </Provider>);};

But in the test itself, I did this:

connectedComponent.setProps({children: <MyComponent params={{}} />});