Asynchronous Assertion Not Awaited
ID |
javascript.async_assertion_not_awaited |
Severity |
critical |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
JavaScript |
Tags |
assertion, async, reliability, testing |
Description
Reports an asynchronous assertion written as a bare statement inside a test: an expect(…).resolves or expect(…).rejects chain, or a Testing Library waitFor(…). All of these return a promise and do their checking on a later turn of the event loop, so a statement that neither awaits nor returns that promise lets the test function finish first.
Only a discarded result is reported. An await, a return, an assignment, a .then() continuation and an argument position such as Promise.all([…]) all hand the promise to code that can settle it.
An expect(…) carrying a promise modifier but no matcher at all is left to javascript.assertions_complete, which reports the missing matcher.
Rationale
// Bad
it('rejects an empty cart', async () => {
expect(charge([])).rejects.toThrow('empty'); // starts checking, waits for nothing
waitFor(() => expect(receipt).toBeVisible()); // polls into the void
});
-
The test is recorded as passed before either assertion has a verdict, so it is green whatever the code under test does.
-
When the assertion does fail, the rejection has no owner: it surfaces as an unhandled rejection charged to whichever test is running by then, or is swallowed entirely.
-
Because both lines read exactly like the awaited form, nothing in review or in the diff points at the missing keyword.
-
The gap survives every later reading of the file, since the test’s title still claims the behaviour is covered.