Enzyme: shallow doesn't work properly with redux connect(store)

Created on 3 Jun 2016  路  13Comments  路  Source: enzymejs/enzyme

related to this issue https://github.com/reactjs/redux/issues/1534, https://github.com/airbnb/enzyme/issues/183

Not sure is this correct place to post, but i encounter a bug when using enzyme with redux
Could not find "store" in either the context or props .... Either wrap the root component in a <Provider>, or explicitly pass "store"

Here is my test

describe("(Component) CoreLayout", () => {
  let _wrapper, _props

  beforeEach(() => {
    _props = {
      children: <anchor/>
    }
    _wrapper = shallow(<CoreLayout {..._props}/>, { context: { store } })
  })

  it('Should render Header', () => {
    console.log(_wrapper.html());
    expect(_wrapper.find('Header')).to.have.length(1)
  })

  it('Should render Footer', () => {
    expect(_wrapper.find('Footer')).to.have.length(1)
  })
})

Header.js

export class Header extends Component {
  static contextTypes = {
    router: PropTypes.object
  }
  render() {
    const { currentUser } = this.props;

    return (
      <div>
        {currentUser.fullName}
      </div>
    )
  }
}

function mapStateToProps(state) {
  return {
    currentUser: state.currentUser
  }
}

I also created my example repo
https://github.com/MQuy/redux-store-enzyme

discussion

Most helpful comment

You can also use dive(). Thus _wrapper.dive().find('Footer')

All 13 comments

I am using redux-mock-store for my unit tests.

import configureStore from 'redux-mock-store';
const mockStore = configureStore();
const dispatch = sinon.spy();

const wrapper = shallow(
    <Test dispatch={dispatch} store={mockStore({ runtime: {} })}
      testData={fakeTestData}
    />
  );

Does this work for you?

@5punk I use redux-mock-store, too 馃槃

Not sure it's correct or not, but I think it's related to our problem
https://github.com/facebook/react/blob/master/src/test/ReactTestUtils.js#L434
The context is passed to that function but, it doesn't work

This issue is really painful as we need to use react-addons for testing in mentioned scenario when child component is connected. In my opinion Unit Test should not pass store via context - we just to test component as a atomic unit.

closing in favor of #472

You can also use dive(). Thus _wrapper.dive().find('Footer')

What we want to test is the actual component itself, so you need to export that and import as
{myComponent} on yourComponent.test

@Zzamanta yes, .dive() lets you do that without having to export/import the inner component.

@Zzamanta thanks! It solved my problem.

@ljharb, managed to my connected, HOC'd component to test like so:

wrapper = shallow(
            <Provider store={store}><SignIn {...props} /></Provider> 
).dive({ context: { store } }).dive();

But componentDidMount() is not triggered. Using mount does trigger componentDidMount() though. Any idea why? [email protected]

Do you have disableLifecycleMethods set anywhere, like perhaps in your configure call?

Do you have disableLifecycleMethods set anywhere, like perhaps in your configure call?

No. It seems I didn't dive deep enough. <Provider> was wrapping <SignIn>, which was wrapped by my own HOC, which was wrapped by connect.
I found that componendDidMount was in fact triggered when I used

wrapper = shallow(
            <Provider store={store}><SignIn {...props} /></Provider> 
).dive({ context: { store } }).dive().dive();

Notice the extra .dive() at the end. I think mount will actually be a better choice as it is properly re-rendering when props are updated in componentDidMount during the test. Thanks @ljharb!

What we want to test is the actual component itself, so you need to export that and import as
{myComponent} on yourComponent.test

This was the easiest solution! However, one also needs to export the corresponding class that is being imported.

export class myComponent extends Component {

Was this page helpful?
0 / 5 - 0 ratings

Related issues

abe903 picture abe903  路  3Comments

heikkimu picture heikkimu  路  3Comments

modemuser picture modemuser  路  3Comments

andrewhl picture andrewhl  路  3Comments

amcmillan01 picture amcmillan01  路  3Comments