Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nested components testing with Enzyme inside of React & Redux

I have a component SampleComponent that mounts another "connected component" (i.e. container). When I try to test SampleComponent by mounting (since I need the componentDidMount), I get the error:

Invariant Violation: Could not find "store" in either the context or props of "Connect(ContainerComponent)". Either wrap the root component in a , or explicitly pass "store" as a prop to "Connect(ContainerComponent)".

What's the best way of testing this?

like image 762
Detuned Avatar asked Jun 13 '16 20:06

Detuned


People also ask

Can we use Enzyme and React testing library together?

Migrating from react-testing-library to EnzymeTo migrate tests from react-testing-library to Enzyme, you'll need to install an additional library called enzyme-adapter-react-[react-version] . This adapter library is necessary and there are different setup steps depending on your version.

Can you nest components in React?

In React, we can nest components inside within one another. This helps in creating more complex User Interfaces. The components that are nested inside parent components are called child components. Import and Export keywords facilitate nesting of the components.


2 Answers

Enzyme's mount takes optional parameters. The two that are necessary for what you need are

options.context: (Object [optional]): Context to be passed into the component

options.childContextTypes: (Object [optional]): Merged contextTypes for all children of the wrapper You would mount SampleComponent with an options object like so:

const store = {    subscribe: () => {},   dispatch: () => {},   getState: () => ({ ... whatever state you need to pass in ... }) } const options = {   context: { store },    childContextTypes: { store: React.PropTypes.object.isRequired }  }  const _wrapper = mount(<SampleComponent {...defaultProps} />, options) 

Now your SampleComponent will pass the context you provided down to the connected component.

like image 187
zentuit Avatar answered Oct 11 '22 19:10

zentuit


What I essentially did was bring in my redux store (and Provider) and wrapped it in a utility component as follows:

export const CustomProvider = ({ children }) => {   return (     <Provider store={store}>       {children}     </Provider>   ); }; 

then, I mount the SampleComponent and run tests against it:

it('contains <ChildComponent/> Component', () => {   const wrapper = mount(     <CustomProvider>       <SampleComponent {...defaultProps} />     </CustomProvider>   );   expect(wrapper.find(ChildComponent)).to.have.length(1); }); 
like image 28
Detuned Avatar answered Oct 11 '22 20:10

Detuned