Hone logo
Hone
Problems

Mastering Async/Await Testing in Jest with TypeScript

This challenge focuses on writing robust and reliable tests for asynchronous JavaScript/TypeScript functions using Jest. Understanding how to properly handle asynchronous operations in tests is crucial for building stable applications, as many modern web APIs and backend interactions rely on promises and async/await.

Problem Description

Your task is to write a Jest test suite in TypeScript for a provided asynchronous function. This function simulates a data fetching operation that returns a Promise. You will need to demonstrate proficiency in using async/await within your Jest tests to correctly assert the outcomes of these asynchronous operations.

Requirements:

  • Write a Jest test suite for the fetchUserData function (provided below).
  • Utilize async/await syntax within your Jest test cases.
  • Test for successful data retrieval.
  • Test for error handling when the data fetch fails.
  • Ensure your tests pass consistently.

Expected Behavior of fetchUserData:

The fetchUserData function simulates fetching user data. It takes a userId as input.

  • If userId is a positive number, it will resolve with a mock user object after a short delay.
  • If userId is 0 or a negative number, it will reject with an Error indicating an invalid user ID.

Edge Cases:

  • Consider what happens if the promise from fetchUserData is not explicitly awaited in the test.

Examples

Let's assume the following fetchUserData function is provided:

// Assume this function is provided and you need to test it
async function fetchUserData(userId: number): Promise<{ id: number; name: string }> {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (userId > 0) {
        resolve({ id: userId, name: `User ${userId}` });
      } else {
        reject(new Error('Invalid User ID'));
      }
    }, 50); // Simulate network delay
  });
}

Example Test Case 1: Successful Data Fetch

// Test for successful data retrieval
test('should fetch user data successfully', async () => {
  const userId = 123;
  const userData = await fetchUserData(userId);
  expect(userData).toEqual({ id: userId, name: `User ${userId}` });
});

Example Test Case 2: Error Handling for Invalid User ID

// Test for error handling
test('should throw an error for invalid user ID', async () => {
  const userId = 0;
  await expect(fetchUserData(userId)).rejects.toThrow('Invalid User ID');
});

Constraints

  • Your tests must be written in TypeScript.
  • You must use Jest as your testing framework.
  • The fetchUserData function is a black box; you should not modify it, only test it.
  • Tests should be concise and easy to understand.

Notes

  • Remember that async functions automatically return Promises.
  • When testing asynchronous operations, always ensure that Jest knows when the asynchronous work is complete. async/await handles this implicitly by allowing you to await the Promise.
  • Consider using expect().resolves and expect().rejects for cleaner assertions on Promises.
  • Think about what might happen if you forget to await a promise within an async test function.
Loading editor...
typescript