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
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
disableLifecycleMethodsset anywhere, like perhaps in yourconfigurecall?
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 {
Most helpful comment
You can also use
dive(). Thus_wrapper.dive().find('Footer')