I'm doing as usual some unit tests with jest and enzyme for one new project. I used to test components that were connected to redux in this way:
a) a store generator
import { createStore } from 'redux';
import rootReducer from '../src/reducers';
export const storeFactory = (initialState) => {
return createStore(rootReducer, initialState);
}
which is consumed by the Input.test.js file
import React from 'react';
import { shallow } from 'enzyme';
import { findByTestAttr,storeFactory } from '../../../test/testUtils';
import Input from './Input';
const setup = (initialState={}) => {
const store = storeFactory(initialState);
const wrapper = shallow(
<Input store={store} />
).dive();
console.log(wrapper.debug());
}
being the example component Input.js:
import React, { Component } from 'react';
import { connect } from 'react-redux';
class Input extends Component {
render(){
return <div />;
}
}
const mapStateToProps = (state) => {
return {};
}
export default connect(mapStateToProps)(Input);
My npm package versions are:
"dependencies": {
"ajv": "^6.6.2",
"react": "^16.7.0",
"react-dom": "^16.7.0",
"react-redux": "^6.0.0",
"react-scripts": "2.1.3",
"redux": "^4.0.1"
}
"devDependencies": {
"check-prop-types": "^1.1.2",
"enzyme": "^3.8.0",
"enzyme-adapter-react-16": "^1.7.1",
"jest": "^23.6.0",
"jest-enzyme": "^7.0.1",
"prop-types": "^15.6.2"
}
And that used to work, but I'm getting this message when running the tests on the tests execution report:
Invariant Violation: Passing redux store in props has been removed and does not do anything. To use a custom Redux store for specific components, create a custom React context with React.createContext(), and pass the context object to React-Redux's Provider and specific components like: . You may also pass a {context : MyContext} option to connect
I tried to pass the context as a parameter of shallow
const setup = (initialState={}) => {
const store = storeFactory(initialState);
const wrapper = shallow(
<Input />, { store }
);
console.log(wrapper.debug());
}
But then I get this logged to console
<ContextConsumer>
[function bound renderWrappedComponent]
</ContextConsumer>
and if I try to use then enzyme dive() method I get:
const setup = (initialState={}) => {
const store = storeFactory(initialState);
const wrapper = shallow(
<Input />, { store }
).dive();
console.log(wrapper.debug());
}
Test suite failed to run
TypeError: ShallowWrapper::dive() can only be called on components
Which is the suggested way of doing it now? I know what the message says but before there was no need of wrapping the element into a Provider for jest/enzyme unit tests. Thank you very much!
Both Jest and Enzyme are meant to test the react applications. Jest can be used with any other Javascript framework, but Enzyme is meant to run on react only. Jest can be used without Enzyme, and snapshots can be created and tested perfectly fine. But the Enzyme adds additional functionality to it.
shallow
and dive
doesn't work as expected in react-redux 6
, so you may want to downgrade it to react-redux 5.0.7
for it to work.
But if you prefer using react-redux 6
, then you might want to use mount
instead.
So, the above code can be rewritten as follows:
Input.test.js
import React from 'react'
import {Provider} from 'react-redux'
import {mount} from 'enzyme'
import {findByAttr, storeFactory} from '../test/testUtils'
import Input from './Input'
const setup = (initialState={}) => {
const store = storeFactory(initialState)
const wrapper = mount(<Provider store={store}><Input /></Provider>)
console.log(wrapper.debug())
}
setup()
Console
console.log src/Input.test.js:11
<Provider store={{...}}>
<Connect(Input)>
<Input dispatch={[Function: dispatch]}>
<div />
</Input>
</Connect(Input)>
</Provider>
And there is another workaround if prefer testing the component as unconnected component, you can still use react-redux 6
and use shallow
; code can be rewritten as follows:
Add export
keyword to Input
Input.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
export class Input extends Component {
render(){
return <div />;
}
}
const mapStateToProps = (state) => {
return {};
}
export default connect(mapStateToProps)(Input);
Input.test.js
import React from 'react';
import { shallow } from 'enzyme';
import { findByTestAttr } from '../../../test/testUtils';
import { Input } from './Input';
const setup = (props={}) => {
const wrapper = shallow(<Input {...props} />);
console.log(wrapper.debug());
}
Console
<div />
Hope this helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With