Hone logo
Hone
Problems

Mocking API Responses with Jest in TypeScript

Testing asynchronous functions that fetch data from APIs can be tricky. To isolate your code and ensure it behaves correctly regardless of external dependencies, you often need to mock the API calls and control the returned data. This challenge focuses on creating mock return values for functions that use fetch in a TypeScript environment using Jest.

Problem Description

You are tasked with creating a Jest test for a function called fetchUserData which fetches user data from a specified URL using the fetch API. The goal is to mock the fetch function to return a predefined response, allowing you to test the fetchUserData function's logic without actually making a network request. You need to ensure that the mocked fetch function is called with the correct URL and that the fetchUserData function correctly parses the mocked response.

What needs to be achieved:

  • Mock the fetch function using Jest's jest.spyOn.
  • Configure the mock to return a specific response object (including status and json methods).
  • Assert that fetch was called with the expected URL.
  • Assert that fetchUserData correctly processes the mocked response.

Key requirements:

  • The fetchUserData function should accept a userId as an argument and construct the URL accordingly.
  • The mocked fetch function should be called with the correct URL.
  • The mocked response's json() method should return a promise that resolves to a specific user object.
  • The test should assert that the fetchUserData function returns the expected user object.

Expected behavior:

The test should pass if the fetch function is mocked correctly, the mock is called with the expected URL, and the fetchUserData function processes the mocked response as expected.

Edge cases to consider:

  • Ensure the URL is constructed correctly based on the userId.
  • The mocked response should simulate a successful HTTP request (status 200).
  • The json() method of the mocked response should return a promise.

Examples

Example 1:

Input: userId = 123
Mocked Response: { json: () => Promise.resolve({ id: 123, name: 'John Doe' }) }
Output: { id: 123, name: 'John Doe' }
Explanation: fetchUserData(123) should fetch from 'https://api.example.com/users/123', mock fetch to return a user object, and the test should assert that the returned user object is { id: 123, name: 'John Doe' }.

Example 2:

Input: userId = 'abc'
Mocked Response: { json: () => Promise.resolve({ id: 'abc', name: 'Jane Smith' }) }
Output: { id: 'abc', name: 'Jane Smith' }
Explanation: fetchUserData('abc') should fetch from 'https://api.example.com/users/abc', mock fetch to return a user object, and the test should assert that the returned user object is { id: 'abc', name: 'Jane Smith' }.

Constraints

  • The fetchUserData function is defined as follows:
async function fetchUserData(userId: string | number): Promise<{ id: string | number; name: string }> {
  const url = `https://api.example.com/users/${userId}`;
  const response = await fetch(url);
  return await response.json();
}
  • You must use jest.spyOn to mock the fetch function.
  • The mocked response must have a json() method that returns a promise.
  • The test should be written in TypeScript.

Notes

  • Consider using jest.mock if you want to mock the entire fetch module, but jest.spyOn provides more granular control.
  • Pay close attention to the asynchronous nature of fetch and promises. Use async/await or .then() appropriately.
  • Think about how to verify that the correct URL was used in the fetch call. mockImplementation can be helpful here.
  • The base URL https://api.example.com/users/ is fixed and should not be changed in your test.
Loading editor...
typescript