Mocking API Calls with Jest in TypeScript
Testing components that rely on API calls can be tricky. Directly hitting external APIs during testing is slow, unreliable (dependent on network conditions and third-party service availability), and potentially costly. This challenge focuses on implementing API mocking using Jest in a TypeScript project to isolate your component logic and ensure predictable test results.
Problem Description
You are tasked with creating a Jest test for a React component called UserProfile. This component fetches user data from an API endpoint (/api/users/123) and displays it. Your goal is to mock the API call using Jest's jest.fn() and fetch mocking capabilities to control the response and verify that the component renders correctly based on the mocked data.
What needs to be achieved:
- Mock the
fetchfunction globally within your test environment. - Configure the mocked
fetchto return a specific response (e.g., a JSON object representing user data). - Ensure the
UserProfilecomponent renders correctly with the mocked data. - Verify that the
fetchfunction was called with the expected URL.
Key Requirements:
- Use Jest and TypeScript.
- Mock the
fetchfunction, not the entire API endpoint. - The
UserProfilecomponent is assumed to be defined elsewhere and is imported into your test file. For this challenge, you don't need to define the component itself, only test it. - The component expects a user object with properties like
name,email, andprofilePicture.
Expected Behavior:
The test should:
- Mock the
fetchfunction to return a predefined JSON response. - Render the
UserProfilecomponent. - Assert that the component displays the data from the mocked response.
- Assert that
fetchwas called with the correct URL (/api/users/123).
Edge Cases to Consider:
- Ensure the mock response is in the correct format (JSON).
- Handle potential errors in the mocked response (though this challenge focuses primarily on successful mock responses).
Examples
Example 1:
Input: Mocked response: { name: "John Doe", email: "john.doe@example.com", profilePicture: "url/to/image.jpg" }
Output: The UserProfile component renders with John Doe's name, email, and profile picture. fetch was called with "/api/users/123".
Explanation: The mock response is used to populate the component, and the fetch call is verified.
Example 2:
Input: Mocked response: { name: "Jane Smith", email: "jane.smith@example.com", profilePicture: null }
Output: The UserProfile component renders with Jane Smith's name and email, and displays a default image (or handles the null profilePicture appropriately, depending on the component's implementation - the test should verify the component's behavior in this case). fetch was called with "/api/users/123".
Explanation: Demonstrates handling a null value in the mocked response.
Constraints
- The test should be written in TypeScript.
- You are allowed to use Jest's built-in mocking functions.
- The
UserProfilecomponent is assumed to be a functional component that usesuseEffectto fetch data. - The test should be concise and readable.
- Performance is not a primary concern for this challenge.
Notes
- Consider using
jest.spyOnto mock thefetchfunction. - You'll need to use a testing library like React Testing Library to render the component and make assertions about its output.
- Think about how to structure your test to clearly isolate the component's behavior from the API call.
- Remember to restore the original
fetchfunction after the test completes to avoid affecting other tests.