Jest Consumer Tests for a Simple API
This challenge focuses on writing consumer-side tests for a hypothetical external API. Consumer-driven contract testing is a powerful technique to ensure that your application (the consumer) and the API it relies on (the provider) remain compatible over time, preventing integration issues.
Problem Description
You are building a TypeScript application that consumes data from a third-party API. This API provides information about products. Your task is to write Jest tests that simulate the behavior of your application when interacting with this API. These tests should verify that your code correctly handles the API's responses, including both successful data retrieval and potential error scenarios.
Specifically, you need to:
- Mock the API: Use Jest's mocking capabilities to simulate network requests to the product API. You will not be making actual HTTP calls.
- Test successful data retrieval: Write a test that verifies your function can successfully fetch and process product data when the API returns a 200 OK response with valid product information.
- Test handling of "Not Found" errors: Write a test that verifies your function correctly handles a 404 Not Found response from the API, perhaps by returning
nullor throwing a specific error. - Test handling of unexpected responses: Write a test that verifies your function gracefully handles unexpected status codes (e.g., 500 Internal Server Error) from the API.
- Test for empty results: Write a test that verifies your function's behavior when the API returns an empty list of products.
Examples
Example 1: Successful Product Fetch
- Input (Simulated API Response):
{ "statusCode": 200, "body": JSON.stringify([ { "id": 1, "name": "Laptop", "price": 1200 }, { "id": 2, "name": "Mouse", "price": 25 } ]) } - Expected Output from your function:
[ { "id": 1, "name": "Laptop", "price": 1200 }, { "id": 2, "name": "Mouse", "price": 25 } ] - Explanation: Your code should make a request to the API, receive a 200 status with a JSON array of products, parse this JSON, and return it as a TypeScript array of product objects.
Example 2: Product Not Found
- Input (Simulated API Response):
{ "statusCode": 404, "body": JSON.stringify({ "message": "Product with ID 99 not found" }) } - Expected Output from your function:
null(or an error, depending on your implementation choice, butnullis preferred for this challenge). - Explanation: When the API indicates a resource is not found (404), your function should return
nullto signify that the requested product does not exist.
Example 3: API Internal Server Error
- Input (Simulated API Response):
{ "statusCode": 500, "body": JSON.stringify({ "message": "Internal server error" }) } - Expected Output from your function: An error should be thrown, e.g.,
new Error("API returned status code 500"). - Explanation: For unexpected server errors, your function should throw a descriptive error to alert the caller that something went wrong on the API side.
Example 4: Empty Product List
- Input (Simulated API Response):
{ "statusCode": 200, "body": JSON.stringify([]) } - Expected Output from your function:
[](an empty array). - Explanation: If the API successfully returns an empty list of products, your function should also return an empty array.
Constraints
- Your solution must be written in TypeScript.
- You must use Jest for testing.
- You should mock the
fetchAPI or any HTTP client library yourgetProductfunction uses. For this challenge, assume your function uses the globalfetchAPI. - The product data will conform to the structure shown in the examples (an array of objects with
id,name, andprice). - Your
getProductfunction should accept a product ID (number) as an argument.
Notes
- You'll need to create a TypeScript function, let's call it
getProduct, that takes aproductIdand returns aPromiseresolving to a product object (ornull) or rejecting with an error. - Consider how you'll mock
fetch. Jest provides mechanisms to mock global objects and modules. - Think about how to structure your tests to cover each scenario clearly. Use
describeanditblocks effectively. - You might want to define interfaces for your
Productand for the structure of the API response for better type safety. - The challenge is about writing the consumer tests. You do not need to implement the actual API provider.