Hone logo
Hone
Problems

Implementing Stub Functions in Jest for TypeScript Projects

Testing asynchronous code and functions that rely on external dependencies can be tricky. Jest provides powerful mocking and stubbing capabilities to isolate your code and verify its behavior without actually executing those dependencies. This challenge focuses on implementing stub functions within Jest tests to control the return values of functions and ensure your code behaves as expected in various scenarios.

Problem Description

You are tasked with writing Jest tests for a TypeScript module that interacts with an external service (simulated by a function fetchData). The fetchData function is asynchronous and returns a Promise that resolves with data from the service. Your goal is to write tests that use stub functions to control the data returned by fetchData and verify that your module handles different scenarios correctly, including success and failure cases. You will be provided with a module containing a function processData that calls fetchData. Your job is to write tests for processData using Jest stubs to mock fetchData and assert the correct behavior of processData based on the mocked return values.

Examples

Example 1: Successful Data Processing

Input: fetchData returns { data: { name: "Alice", age: 30 } }
Output: processData returns "Alice is 30 years old."
Explanation: processData receives the data from fetchData and formats it into a string.

Example 2: Error Handling

Input: fetchData rejects with an error "Network Error"
Output: processData returns "Error: Network Error"
Explanation: processData catches the error from fetchData and returns an error message.

Example 3: Empty Data

Input: fetchData returns { data: {} }
Output: processData returns "No data available."
Explanation: processData receives an empty object and returns a default message.

Constraints

  • The fetchData function is asynchronous and returns a Promise.
  • The processData function must be tested using Jest stubs.
  • Tests should cover both successful and error scenarios.
  • The tests should be written in TypeScript.
  • You are provided with the processData function and the fetchData function signature. You do not have access to the implementation of fetchData.

Notes

  • Use jest.fn() to create stub functions.
  • Use mockResolvedValue() or mockRejectedValue() to control the return values of the stub functions.
  • Use expect to assert the return values of processData.
  • Consider using async/await for cleaner asynchronous testing.
  • Focus on testing the behavior of processData, not the implementation of fetchData.
// Provided Module (do not modify)
export async function fetchData(): Promise<{ data: any }> {
  // Simulate fetching data from an external service
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      // Simulate a network request
      const success = Math.random() > 0.2; // 80% chance of success
      if (success) {
        resolve({ data: { name: "Bob", age: 25 } });
      } else {
        reject(new Error("Network Error"));
      }
    }, 50);
  });
}

export async function processData(data: { data: any }): Promise<string> {
  try {
    if (!data || !data.data) {
      return "No data available.";
    }

    const { name, age } = data.data;

    if (name && age) {
      return `${name} is ${age} years old.`;
    } else {
      return "Incomplete data.";
    }
  } catch (error: any) {
    return `Error: ${error.message}`;
  }
}
Loading editor...
typescript