← Concepts

阅读中文版本

Async Assertion Patterns

Async assertions bridge test time and promise time: awaiting results, polling conditions with deadlines, and asserting on settled state — or the suite reports the wrong failure or none at all.

testing

Definition

Testing asynchronous code requires synchronization between the test body and eventual outcomes. Patterns: direct await of the promise under test; polling waitFor with timeout and interval for conditions that settle indirectly; fake timers to control virtual time deterministically; and careful distinction between a rejected assertion and a timed-out wait, which are different failures.

Context and scope

Every test suite touching async boundaries: UI state settling, message consumers processing, retries and eventual consistency converging.

Common misconceptions

  • Returning the promise is enough — a returned promise covers direct outcomes; indirect convergence — consumer processed, cache refreshed — needs explicit waits
  • Sleeping a fixed delay is a safe default — sleeps set test duration equal to the worst case and still flake under CI contention; poll with deadline instead
  • A timeout means the feature is broken — it means the condition did not settle in the window; the cause may be the test environment or the assertion itself

Anti-patterns

  • Asserting immediately after firing an async operation and reading not-yet-updated state
  • Sleeping 500ms everywhere and shipping a suite that takes an hour and still flakes
  • Swallowing rejection paths by asserting only on success, so error branches never execute in any test

Related concepts

Related examples

Authoritative source

https://jestjs.io/docs/asynchronous-testing

What it is

The test body ends before the asynchronous world does. Without synchronization, assertions run against half-completed state and fail for reasons unrelated to the bug — or pass vacuously because nothing threw before the process exited.

How it works

Direct promises: return or await them so the framework awaits settlement. Eventual conditions: poll with a deadline — fast when it settles early, bounded when it never does. Virtual time: fake timers advance instantly past retries and backoffs. Failure triage distinguishes assertion failure from synchronization timeout by message and by design.

When to apply

Any test asserting state changed by callbacks, workers, or eventual consistency. Combine fake timers with real-time polling rarely and deliberately — mixing time domains breeds subtle nondeterminism.

Pitfalls

Vacuous tests: async functions that resolve without asserting anything report green. Unhandled rejections escape the test boundary and crash unrelated cases. Polling intervals below the systems eventual-consistency window produce systematic flakes — the deadline must exceed the worst legitimate convergence time.