Hone logo
Hone
Problems

Testing Asynchronous Code with jest.useFakeTimers()

Testing asynchronous code, particularly code that relies on setTimeout, setInterval, or promises, can be tricky in Jest. jest.useFakeTimers() allows you to control the passage of time in your tests, enabling you to advance timers and assert that asynchronous operations complete as expected. This challenge will guide you through implementing and utilizing jest.useFakeTimers() to effectively test asynchronous functions.

Problem Description

You are tasked with creating a TypeScript function delayedGreeting that takes a name and a delay (in milliseconds) as input. The function should return a promise that resolves to a greeting string after the specified delay. Your goal is to write a Jest test suite that uses jest.useFakeTimers() to verify that the promise resolves with the correct greeting after the expected delay, without waiting for the actual time to pass. You must also demonstrate how to manually advance the fake timers to trigger the promise resolution.

Key Requirements:

  • Implement the delayedGreeting function.
  • Use jest.useFakeTimers() in your test suite.
  • Advance the fake timers using jest.advanceTimersByTime() or jest.runAllTimers().
  • Assert that the promise resolves with the expected greeting string.
  • Clean up the fake timers using jest.resetAllTimers() after each test.

Expected Behavior:

The test suite should pass only when the delayedGreeting function behaves as expected, resolving the promise with the correct greeting after the specified delay. The tests should not take the actual delay time to complete.

Edge Cases to Consider:

  • Ensure the test suite cleans up the fake timers after each test to prevent interference between tests.
  • Consider how to handle potential errors within the delayedGreeting function (although error handling is not the primary focus of this challenge).

Examples

Example 1:

Input: delayedGreeting("Alice", 1000)
Output: Promise<string> resolves to "Hello, Alice!" after 1000ms (in real time, but instantly in the test)
Explanation: The function creates a timeout that resolves the promise after 1000ms.  In the test, we use `jest.useFakeTimers()` and `jest.advanceTimersByTime(1000)` to simulate the passage of 1000ms and trigger the promise resolution.

Example 2:

Input: delayedGreeting("Bob", 500)
Output: Promise<string> resolves to "Hello, Bob!" after 500ms (in real time, but instantly in the test)
Explanation: Similar to Example 1, but with a shorter delay.

Constraints

  • The delayedGreeting function must be implemented in TypeScript.
  • The test suite must be written in Jest and TypeScript.
  • The delay time will always be a positive integer (greater than 0).
  • The name parameter will always be a non-empty string.
  • Tests should complete within a reasonable timeframe (less than 1 second).

Notes

  • jest.useFakeTimers() globally enables fake timers for all tests in the current file.
  • jest.advanceTimersByTime(ms) advances the fake timers by the specified number of milliseconds.
  • jest.runAllTimers() executes all pending timers immediately.
  • jest.resetAllTimers() resets all timers to their initial state and clears any pending timers. This is crucial for test isolation.
  • Consider using async/await to simplify the assertion of the promise resolution.
Loading editor...
typescript