I'm using React Test Renderer with Jest to test my React Native app.
Here is a simple code example of what I'm doing:
it('renders one text', () => {
const text = 'bar';
const instance = renderer.create(
<View>
<Text testID="foo">{text}</Text>
</View>
).root;
expect(instance.findAllByProps({ testID: 'foo' }).length).toEqual(1);
});
it('renders two texts', () => {
const text = 'bar';
const instance = renderer.create(
<View>
<Text testID="foo">{text}</Text>
<Text testID="foo">{text}</Text>
</View>
).root;
expect(instance.findAllByProps({ testID: 'foo' }).length).toEqual(2);
});
The first test fails saying:
Expected: 1
Received: 2
And the second test also fails:
Expected: 2
Received: 4
Why does react test renderer using findAllByProps
find double the instances?
PS: As a sanity check I also tried findByProps
which works:
it('renders one text', () => {
const text = 'bar';
const instance = renderer.create(
<View>
<Text testID="foo">{text}</Text>
</View>
).root;
expect(instance.findByProps({ testID: 'foo' }).props.children).toEqual(text);
});
Create a TestRenderer instance with the passed React element. It doesn’t use the real DOM, but it still fully renders the component tree into memory so you can make assertions about it. Returns a TestRenderer instance. Similar to the act () helper from react-dom/test-utils, TestRenderer.act prepares a component for assertions.
I've taken a deeper look into it and it turns out that under certain conditions findAllByPropsmay return two TestInstances matching the query, however those do not represent the same entity. The first entity represents the props passed to the component, the second the actual component with it's whole structure and props applied.
6 There is unresolved issue on react-native Currently the only work-around is: const findAllByTestID = (instance) => instance.findAll(el => el.props.testID === 'foo' && el.type === 'Text'); expect(findAllByTestID(instance).length).toEqual(2);
This package provides a React renderer that can be used to render React components to pure JavaScript objects, without depending on the DOM or a native mobile environment.
There is unresolved issue on react-native
Currently the only work-around is:
const findAllByTestID = (instance) => instance.findAll(el => el.props.testID === 'foo' && el.type === 'Text');
expect(findAllByTestID(instance).length).toEqual(2);
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