DrMister DrMister - 2 months ago 20
React JSX Question

Jest snapshot different when testing through CI vs locally

I've implemented jest snapshot testing, which works great. Only thing I can't solve is that my component is rendering a different snapshot on my CI. My test is:

/* eslint-env jest */
/* eslint import/no-extraneous-dependencies: "off" */

import React from 'react';
import { shallow } from 'enzyme';
import { shallowToJson } from 'enzyme-to-json';
import Combobox from '../Combobox';

describe('<Combobox />', () => {
it('renders correctly', () => {
const wrapper = shallow(
<Combobox
items={[]}
placeholder=""
valueKey=""
labelKey=""
/>
);

expect(shallowToJson(wrapper)).toMatchSnapshot();
});
});


And the component is:

import React, { PropTypes } from 'react';
import Select from 'react-select';

export default class Combobox extends React.Component {
constructor(props) {
super(props);
this.state = {
currentValue: null,
};
this.updateValue = this.updateValue.bind(this);
}

updateValue(newValue) {
this.setState({
currentValue: newValue,
});
}

render() {
return (
<Select
placeholder={this.props.placeholder}
valueKey={this.props.valueKey}
labelKey={this.props.labelKey}
options={this.props.items}
value={this.state.currentValue}
onChange={this.updateValue}
/>
);
}
}

Combobox.propTypes = {
items: PropTypes.array.isRequired,
placeholder: React.PropTypes.string.isRequired,
valueKey: React.PropTypes.string.isRequired,
labelKey: React.PropTypes.string.isRequired,
};


I'm using
enzyme
and
enzyme-to-json
to generate the snapshot. The component itself is a wrapper around
react-select
. When testing locally everything is fine, but on my CI it errors with:

FAIL src/components/__tests__/Combobox.test.jsx
● <Combobox /> › renders correctly

Received value does not match the stored snapshot 1.

- Snapshot
+ Received

<Select
// ...
- optionComponent={[Function anonymous]}
+ optionComponent={[Function Constructor]}
// ...
- valueComponent={[Function anonymous]}
+ valueComponent={[Function Constructor]}
valueKey="" />

at Object.<anonymous> (src/components/__tests__/Combobox.test.jsx:20:82)
at process._tickCallback (internal/process/next_tick.js:103:7)


So
optionComponent
and
valueComponent
have different values, compared to my local snapshots. What could be causing this discrepancy between my local and my remote tests?

Answer

This is a known issue and will be fixed in Jest v16 (source). Fixed in PR #1752.

There is a problem how Node.js handles function names. It should be OK if you use the exact same version of Node.js on local machine and CI.

For your information, the solution in JEST will be to remove the name from the snapshot. It will look like this:

optionComponent={[Function]}

A trick/hack pointed in the issue is to wrap the function in an anonymous function:

-      onSelect={onSelectHandler}
+      onSelect={(...args) => onSelectHandler(...args)}

Unfortunately, this would have to happen in the react-select library.