-
Notifications
You must be signed in to change notification settings - Fork 153
Description
What rule do you want to change?
no-wait-for-multiple-assertions
Does this change cause the rule to produce more or fewer warnings?
Fewer warnings
How will the change be implemented?
The rule no-wait-for-multiple-assertions currently forbids any multiple assertions inside a waitFor callback.
The proposal is to refine the rule so that it only reports an error when multiple assertions are made against the same asynchronous target.
This keeps the original intention (avoid useless timeouts when combining multiple checks on the same async call) while avoiding unnecessary errors in cases where separate async targets are being tested together.
Example code
await waitFor(() => { expect(window.fetch).toHaveBeenCalledWith('/foo'); expect(localStorage.setItem).toHaveBeenCalledWith('bar', 'baz'); });
I think this should be allowed, since the assertions are checking different async targets (fetch and localStorage).
Currently the rule reports this as an error, but splitting them into separate waitFor calls adds verbosity without reducing timeout risks.
How does the current rule affect the code?
- It flags all multiple assertions inside
waitFor
, even when they target different async behaviors. - This often forces developers to artificially split assertions into multiple waitFor calls, which can hurt readability and lead to more verbose tests.
How will the new rule affect the code?
- Multiple assertions against the same async target will still be forbidden.
- Multiple assertions against different async targets will be allowed.
- Developers will no longer need to split unrelated assertions into separate waitFor calls.
Anything else?
There are also practical cases where multiple assertions in the same waitFor should be acceptable, because they are targeting different async targets and are expected to resolve independently. For example:
export function Example() { const [a, setA] = useState(''); const [b, setB] = useState(''); useEffect(() => { setTimeout(() => setA('a'), 100); setTimeout(() => setB('b'), 500); }, []); return ( <div> <div data-testid="a">{a}</div> <div data-testid="b">{b}</div> </div> ); } it('Example', async () => { render(<Example />); await waitFor(() => { expect(screen.getByTestId('a')).toHaveTextContent('a'); // ⚠️ This triggers a lint error, but shouldn't it be acceptable here? expect(screen.getByTestId('b')).toHaveTextContent('b'); }); });
In this case, both a
and b
are independent async state updates.
Splitting them into two separate waitFor calls does not reduce the timeout risk (if one fails, it will still time out), but it does add verbosity.
Allowing multiple assertions on different async targets would make this kind of test more concise without sacrificing reliability.
Since the blog post Common mistakes with React Testing Library
mainly highlights the benefits of avoiding multiple assertions when they target the same async behavior(ex: window.fetch
), I’m wondering if for different async targets it might not be necessary to split them. What do you think?
Similar discussion: https://github.com/testing-library/eslint-plugin-testing-library/discussions/595?utm_source=chatgpt.com
Do you want to submit a pull request to change the rule?
Yes