JavaScript · Advanced level

Advanced level · Module 1: Testing JavaScript · Lesson 2 of 4

Testing Asynchronous Code and Using Test Doubles

Test promises and async functions, control timers and replace slow or unreliable dependencies with test doubles.

In this lesson you will

  • Test async functions and rejected promises
  • Use fakes and mocks for fetch and time

Key concepts

async testsassert.rejectsfake and mockdependency injection

The lesson

Test async functions by making the test async and awaiting the result. To check failures, use assert.rejects(promise, ErrorType). Forgetting to await an assertion makes a test pass even when the code is wrong.

Tests should not depend on the real network or the real clock. Pass dependencies in — for example an api client created with createApi({ fetch }) — so tests can supply a fake fetch that returns prepared responses or errors.

Mocks record how they were called, which is useful for checking that a function retried twice. Use them sparingly; tests that check every internal call break whenever the implementation changes.

Step by step

  1. Test an async function that resolves.
  2. Test one that rejects with assert.rejects.
  3. Inject a fake fetch into the API client.
  4. Simulate a timeout and check the fallback.

Practice activity

Test the budget app's API client for success, HTTP error, timeout and offline fallback using a fake fetch.

Expected result: All four scenarios are tested without touching the network.

Check your understanding

  1. Why should tests not call the real network?

    Show answer

    It makes them slow, unreliable and dependent on outside services.

  2. How can a fake fetch be given to code under test?

    Show answer

    By injecting it as a dependency, for example as a function parameter.

Taught live by an instructor — online or in person. Free course lessons are for self-study and do not lead to a certificate — see registration options.