Hone logo
Hone
Problems

Jest Manual Mocking for API Service

This challenge focuses on creating manual mocks for external API services in Jest. Unit testing often requires isolating the code under test from its dependencies, such as network requests or database interactions. By manually mocking these dependencies, we can control their behavior and ensure our tests are reliable and fast.

Problem Description

You are tasked with testing a UserService class that depends on an external ApiService. The ApiService is responsible for making HTTP requests to fetch user data. Your goal is to write Jest tests for UserService without actually making real HTTP requests. To achieve this, you will create a manual mock for the ApiService.

The UserService class has a method getUserDetails(userId: string) which calls ApiService.get(/users/${userId}).

Your task involves:

  1. Creating a manual mock for the ApiService module.
  2. Configuring the mock to simulate different API responses (e.g., successful user retrieval, user not found, network error).
  3. Writing Jest tests for the UserService.getUserDetails method using the mocked ApiService.

Examples

Example 1: Successful User Retrieval

  • Scenario: The ApiService successfully returns user data for a given userId.
  • Input to Test: userService.getUserDetails('123')
  • Mocked ApiService.get Behavior: Resolves with a promise containing user data:
    { "id": "123", "name": "Alice", "email": "alice@example.com" }
    
  • Expected Output from userService.getUserDetails('123'):
    Promise<{ id: string; name: string; email: string }> // Resolved with the user data
    
  • Explanation: The UserService successfully fetches and returns the user details by leveraging the mocked ApiService.

Example 2: User Not Found

  • Scenario: The ApiService returns a 404 Not Found error.
  • Input to Test: userService.getUserDetails('456')
  • Mocked ApiService.get Behavior: Rejects with an error object simulating a 404:
    new Error("User with ID 456 not found."); // Or a more specific error structure
    
  • Expected Output from userService.getUserDetails('456'):
    Promise<null | undefined> // Or a specific error thrown by UserService
    
  • Explanation: The UserService should handle the "not found" scenario gracefully, perhaps by returning null or undefined, or by re-throwing a more specific error.

Example 3: Network Error

  • Scenario: The ApiService encounters a network error during the request.
  • Input to Test: userService.getUserDetails('789')
  • Mocked ApiService.get Behavior: Rejects with a generic network error:
    new Error("Network error.");
    
  • Expected Output from userService.getUserDetails('789'):
    Promise<null | undefined> // Or a specific error thrown by UserService
    
  • Explanation: The UserService should catch network errors and handle them appropriately, potentially returning null or undefined, or re-throwing a custom error.

Constraints

  • The ApiService is assumed to be an external module that you cannot modify.
  • Your solution must use Jest's manual mocking capabilities.
  • Tests should be written in TypeScript.
  • The mocked ApiService should have a get method that returns a Promise.

Notes

  • Consider how to reset the mock's behavior between different test cases.
  • Think about how you will assert that the ApiService.get method was called with the correct URL.
  • You will likely need to create a __mocks__ directory for your ApiService.
  • The structure of the ApiService and UserService will be provided, but you will need to implement the mocks and tests.
Loading editor...
typescript