I am facing attached error while performing snapshot testing. The error is basically for dropdown and datepicker of kendo controls.
4 Answers
The way I'd approach this problem is with Jest Property Matchers, so you can expect any string. That way, dynamic strings will still pass.
Without a code sample from the OP it's not really possible to suggest a concrete implementation, but from a testing perspective this will be much easier than trying to inject a UUID into every component that requires it.

- 710
- 6
- 23
-
Property matchers only work for objects, not HTML. – Ardweaden Oct 18 '22 at 15:39
-
@Eric Dauenhauer: This is a really helpful pointer, as I'm dealing with some dynamic `id`s that keep making my snapshot match fail. However, a typical component like `const tree = renderer.create(
).toJSON()` creates a pretty complicated nested object, containing all the divs and elements. How might I run a property matcher if I've got a complicated nested object? Any pointers? – twknab Dec 14 '22 at 20:51 -
1@twknab I don't think there is a great "one size fits all" approach, but typically when I find my data structure too complicated to assert on as a whole, I'll assert on specific parts of it. For example: `expect(myBigJson.prop.nested[0]).toMatchInlineSnapshot()`, and repeat as needed for as many props as you feel are important to assert on – Eric Dauenhauer Dec 15 '22 at 23:18
If the ID is dynamically generated, such as a UUID, then it will always be different if generated by the component, so your snapshot test will always fail.
Instead you should generate the ID outside the component and pass it in as a prop. That way you can hard-code that prop in the test, ensuring it remains consistent between test runs.
You can still generate the ID inside the component if you need to, but have it only do so if one isn't passed in. So if an ID is passed in, use that, otherwise generate one.
For example:
import React, {Component} from 'react';
import {v4} from 'uuid';
export default class MyComponent extends Component {
constructor(props) {
super(props);
let id = props.id;
if (!id) {
id = v4();
}
this.state = {
id: id
}
}
render() {
return (
<div id={this.state.id}>
<div>
);
}
}
Obviously the exact code will depend on what UUID library you use (I used the uuid
one). Then, in your test, explicitly pass through the id as a prop like this:
<MyComponent id="foo" />
For use cases where ID's or other dynamic content is generated, it's possible to allow it to match them. The documentation gives this example:
it('will check the matchers and pass', () => {
const user = {
createdAt: new Date(),
id: Math.floor(Math.random() * 20),
name: 'LeBron James',
};
expect(user).toMatchSnapshot({
createdAt: expect.any(Date),
id: expect.any(Number),
});
});
While this doesn't give a specific example of using this in the context of a React component, it does illustrate that it can be done with dynamic values. It is, however, much easier if you can pass the values through explicitly rather than have something in your component generate them.

- 9,212
- 2
- 42
- 83
-
-
-
Thanks for the example. But in my case as show in screenshot, the attributes for which id's are dynamically getting changed are not part of my control. The aria-controls, aria-activedescend are dynamically getting added inside the dom – Parag Pathari Nov 20 '18 at 22:32
-
@ParagPathari If they're being added by the Javascript library your component wraps, then that's problematic, because if you can't guarantee that it will render exactly the same every time it's rendered, you can't create a useful snapshot test. When do you call Kendo? You should do so in `componentDidMount()`, in which case it should be possible to work around this. Or can you pass an ID into Kendo? – Matthew Daly Nov 20 '18 at 22:56
-
@ParagPathari Although there is an approach described at https://github.com/facebook/jest/blob/master/docs/SnapshotTesting.md#property-matchers which should cover your use case. I'll pop something in the answer. – Matthew Daly Nov 20 '18 at 23:01
After few hours, i finally find something that fit for me. Especially these svg are nested children, so i couldn't use the expect.any(String) as param in the toMatchSnapshot()
In your setupFiles, write the following:
jest.mock("path/to/your/main/icon/component", () => "svg");
My previous snapshot with dynamic id integration:
<svg
className="sc-gsDKAQ csGOgr"
color="#FFFFFF"
fill="currentColor"
height="2.4rem"
id="5209.3159726668255"
isopen="0"
style="margin-left: 1.7rem;"
viewBox="0 0 20 20"
width="2.4rem"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M4.516 7.548c0.436-0.446 1.043-0.481 1.576 0l3.908 3.747 3.908-3.747c0.533-0.481 1.141-0.446 1.574 0 0.436 0.445 0.408 1.197 0 1.615-0.406 0.418-4.695 4.502-4.695 4.502-0.217 0.223-0.502 0.335-0.787 0.335s-0.57-0.112-0.789-0.335c0 0-4.287-4.084-4.695-4.502s-0.436-1.17 0-1.615z"
/>
</svg>
After this setup:
<svg
className="sc-gsDKAQ csGOgr"
height="2.4rem"
name="cutArrowDown"
style="margin-left: 1.7rem;"
width="2.4rem"
/>
So now im free to use my toMatchSnapshot() without worrying that it will break everytime with these dynamic id.
Pass you id as a prop from a parent component and defaultProps to give your Id a default value, so that the value doesn't get to change when you are running your test.
In the example below, your id will always be 1 when you run your test:
import React from 'react'
import PropTypes from 'prop-types'
const AwesomeComponent = props => {
const {id} = props.id
return <p>My Id is: {id}</p>
}
AwesomeComponent.propTypes = {
id: PropTypes.number
}
AwesomeComponent.defaultProps = {
id: 1
}
export default AwesomeComponent

- 4,045
- 6
- 47
- 68