Reputation: 183
Due to the complexity of the application I am working on I have decided on using a nested redux container rather than passing an action as a prop down to the child components. However, this has proved to be problematic for unit testing when rendering the OuterContainer
with jsdom in combination with mocha
, chai
and sinon
.
Here is a contrived example of the view structure:
<OuterContainer>
<div>
<InnerContainer />
</div>
</OuterContainer>
where OuterContainer
& InnerContainer
are wrapped with connect. e.g.:
export connect(<mapStateToProps>)(<Component>)
When running tests the error I am getting is:
Invariant Violation: Could not find "store" in either the context or props of "Connect(Component)". Either wrap the root component in a `<Provider>`, or explicitly pass "store" as a prop to "Connect(Component)".
Is there a way to unwrap or stub the InnerContainer
for unit testing without having to use shallow rendering?
Upvotes: 18
Views: 5328
Reputation: 480
Mock the Provider
component to return the child component.
Add this before describe()
.
jest.mock('Provider', () => ({children}) => children);
Upvotes: 0
Reputation: 1
Not sure if this is what your problem is, but I'm sure this will probably help a few people out there looking at this feed.
I had the same error and it was a simple fix:
I had forgotten to pass my component my store object in my entry file (using webpack).
I just added an attribute to the Root component "store={store}" see below:
document.addEventListener("DOMContentLoaded", () => {
const store = configureStore();
ReactDOM.render(<Root store={store} />,
document.getElementById('content'));
});
This was my root file code for reference as well:
import React from 'react';
import { Provider } from 'react-redux';
import App from './app';
const Root = ({ store }) => (
<Provider store={ store }>
<App />
</Provider>
);
export default Root;
Hope that helps someone!
Upvotes: 0
Reputation: 14734
Another approach is to export both the component to be connected and the container. The container as default, of course.
export const Comp = (props) => (<p>Whatever</p>)
export default connect(...)(Comp)
Hence, you can unit test Comp
.
Upvotes: 0
Reputation: 268255
Wrap your component in <Provider>
when testing. It’s up to you whether to supply a real store or a mock with { dispatch, getState, subscribe }
to it. Wrapping the outermost component in <Provider store={store}>
will also make the store available to the child components at any level of nesting—just like in the app itself.
const store = createStore(reducer) // can also be a mock
ReactTestUtils.renderIntoDocument(
<Provider store={store}>
<OuterContainer />
</Provider>
)
Upvotes: 23