Simulate runs out of sync with rest of test when using react state hook
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 19.8k
- Forks
- 2k
- PR merge metrics
- No merged PRs in 30d
Description
Running simulate on a node that updates a react state runs the simulate event before any tests.
E.g.
DemoComponent.js
```
import React, { useState } from 'react';
const DemoComponent = ({
}) => {
const [state, setState] = useState(false);
return (
setState(!state)}
>
Click Me
);
};
export default DemoComponent;
```
DemoComponent.test.js
Test that passes
```
import React from 'react';
import { shallow, mount } from 'enzyme';
import DemoComponent from './DemoComponent';
describe('Demo Test', () => {
it('renders', () => {
shallow();
});
const wrapper = mount(
,
);
// CONSOLE LOG 01
console.log(wrapper.find('.selectMe').html());
it('has class off by default', () => {
expect(wrapper.find('.selectMe').hasClass('off')).toEqual(true);
});
});
```
DemoComponent.test.js
Test that Fails
```
import React from 'react';
import { shallow, mount } from 'enzyme';
import DemoComponent from './DemoComponent';
describe('Demo Test', () => {
it('renders', () => {
shallow();
});
const wrapper = mount(
,
);
// CONSOLE LOG 01
console.log(wrapper.find('.selectMe').html());
it('has class off by default', () => {
expect(wrapper.find('.selectMe').hasClass('off')).toEqual(true);
});
wrapper.find('button').simulate('click');
// CONSOLE LOG 02
console.log(wrapper.find('.selectMe').html());
});
```
Output of Console log 01
`
Output of Console log 02
`
As you can see the dom is updating in order (The class start as 'off' then after the button is clicked it goes to 'on' but the test thinks the button click has been simulated before the first has class test.
**Update**
It works if simulate and expect are both inside the same 'it()'
e.g.
Working code:
```
import React from 'react';
import { shallow, mount } from 'enzyme';
import DemoComponent from './DemoComponent';
describe('Demo Test-Initial', () => {
const wrapper = mount(
,
);
it('has class off by default', () => {
expect(wrapper.find('.selectMe').hasClass('off')).toEqual(true);
});
it('has class on after click', () => {
wrapper.find('button').simulate('click');
expect(wrapper.find('.selectMe').hasClass('on')).toEqual(true);
});
});
```
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by running the reproduced cases in DemoComponent.js and DemoComponent.test.js, comparing the test ordering around mount, the initial class assertion, and simulate('click'). Confirm the behavior with the working and failing examples; done means the initial assertion observes the default state before the simulated click and the later assertion observes the updated state.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, react
- Domain
- frontend, testing
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100