Reputation: 4209
I'm trying to use shallow from enzyme and also use snapshots from jest together.
The problem I'm facing is that I need to change something from the state using setState()
from enzyme and then match the result with the snapshot.
See the code of my component:
....
getPrevProduct = () => {
const key = this.state.indexCurrent > 0 &&
this.productsKeys[this.state.indexCurrent - 1];
let product = null;
if (key) {
product = this.props.products[key];
}
return product;
}
renderPrev = () => this.getPrevProduct() && <PrevButton />;
render() {
return (
<div>
...
{this.renderPrev()}
...
<div>
)
}
The previous code checks if the product, passed from props in the currentIndex, exists.
That's why I need Enzyme to change the state. Then, if it matches, <PrevButton />
has to be rendered.
This test is when I want to match the component with the snapshot:
const nextProps = {
products: {
test: 'test'
}
};
const tree = create(<Component nextProps={nextProps} />).toJSON();
expect(tree).toMatchSnapshot();
But I need to change the state. How I can do that? This doesn't work:
it('should render component with prev button', () => {
const nextProps = {
products: {
test: 'test'
}
};
const instance = shallow(<Component nextProps={nextProps} />).instance()
instance.setState({
indexCurrent: 1
});
const tree = create(<Component nextProps={nextProps} />).toJSON();
expect(tree).toMatchSnapshot();
});
I also tried to save the declaration of the component into a variable like the next uncompleted code and use it in shallow
and create
:
const component = <Component nextProps={nextProps} />;
shallow(component).instance()).instance()
create(component).toJSON()`
I also tried with no luck enzyme-to-json.
What would you do?
Upvotes: 5
Views: 5981
Reputation: 401
Install enzyme-to-json
npm install --save-dev enzyme-to-json
Update your jest config:
"jest": {
"snapshotSerializers": [
"enzyme-to-json/serializer"
]
}
Test
it('works', () => {
const wrapper = shallow(<MyComponent />)
expect(wrapper).toMatchSnapshot()
})
Original: https://devhints.io/enzyme#installing
Upvotes: 5
Reputation: 3560
Probably, its not the way enzyme-to-json
is supposed to be used. Try this way :
import { shallowToJson } from 'enzyme-to-json';
import { shallow } from 'enzyme';
and then in your test :
const wrapper = shallow(<Component />);
expect(shallowToJson(wrapper)).toMatchSnapshot();
Upvotes: 7
Reputation: 4209
After trial and error, I found that enzyme has a method, not documented (or I didn't find it) called getRenderOutput
.
That method return the component in JSON format so I can do that:
it('should render component with prev button', () => {
const nextProps = {
products: {
test: 'test'
}
};
const render = shallow(mockComponent(nextProps))
const instance = render.instance();
instance.setState({
indexCurrent: 1
});
const tree = render.renderer.getRenderOutput();
expect(tree).toMatchSnapshot();
});
That's how I can use snapshots from Jest with enzyme.
The only problem with getRenderOutput
is that if I put a console log, it will be printed twice. That's because instance()
and getRenderOutput()
, both fires the test.
This is the output of the snapshot:
exports[`ProductNavigator should render component with prev button 1`] = `
<div>
<FloatingActionButton
className="NavigatorButton left"
onTouchTap={[Function]}
secondary={true}
>
<KeyboardArrowLeft />
</FloatingActionButton>
</div>
`;
If someone knows a better way to do that, please, add a comment.
Thanks!
Upvotes: 2