Hone logo
Hone
Problems

Testing with Mock Implementations in Jest (TypeScript)

Unit testing often requires interacting with external dependencies like APIs, databases, or complex modules. Directly testing against these dependencies can be slow, unreliable (due to network issues or database availability), and can couple your tests to the external system. This challenge focuses on creating mock implementations of dependencies using Jest to isolate your code and ensure focused, reliable unit tests.

Problem Description

You are tasked with creating a mock implementation of a DataFetcher class. The DataFetcher class is responsible for fetching data from an external API. Your goal is to write a Jest test that uses this mock implementation to verify that a function, processData, correctly handles the data returned by the DataFetcher. The processData function should take a DataFetcher instance as a dependency and perform some operations on the fetched data. You need to mock the fetchData method of the DataFetcher to control the data returned to processData and assert that processData behaves as expected given different mock data scenarios.

Key Requirements:

  • Create a mock implementation of the DataFetcher class using Jest's mockImplementation or mockResolvedValue methods.
  • Verify that processData calls fetchData on the DataFetcher instance.
  • Verify that processData processes the mocked data correctly, based on assertions within the function.
  • Handle potential edge cases where the mocked data might be empty or invalid.

Expected Behavior:

The test should pass if the processData function correctly utilizes the mocked DataFetcher and behaves as expected based on the mocked data. The test should fail if processData does not call fetchData, or if it processes the data incorrectly.

Edge Cases to Consider:

  • What happens if the mocked data is an empty array?
  • What happens if the mocked data contains unexpected values or types?
  • Does processData handle errors gracefully if fetchData were to reject (though we're mocking, consider the design)?

Examples

Example 1:

Input:
DataFetcher mock returning: [{ id: 1, name: 'Item 1' }, { id: 2, name: 'Item 2' }]
processData(fetcher) -  processData is designed to return the number of items.

Output: 2
Explanation: processData should correctly count the items returned by the mocked DataFetcher.

Example 2:

Input:
DataFetcher mock returning: []
processData(fetcher) - processData is designed to return 0 if no items are found.

Output: 0
Explanation: processData should handle the empty array case gracefully and return 0.

Example 3:

Input:
DataFetcher mock returning: [{ id: 1, name: 'Item 1' }, { id: 2, name: null }]
processData(fetcher) - processData is designed to filter out items with null names.

Output: 1
Explanation: processData should filter out the item with the null name and return the count of valid items.

Constraints

  • The DataFetcher class is defined as follows:

    interface DataItem {
        id: number;
        name: string | null;
    }
    
    class DataFetcher {
        async fetchData(): Promise<DataItem[]> {
            throw new Error("Method not implemented.");
        }
    }
    
  • The processData function is defined as follows:

    function processData(fetcher: DataFetcher): number {
        // Your implementation here
        return 0;
    }
    
  • You must use Jest's mocking capabilities to create the mock implementation of DataFetcher.

  • The test should be written in TypeScript.

Notes

  • Consider using jest.mock to mock the entire DataFetcher class.
  • Think about how to structure your assertions to verify both the calls to fetchData and the resulting data processing.
  • Focus on isolating the processData function by controlling its dependency on the DataFetcher.
  • The processData function's implementation is not provided; you must write it to be testable with the mock. It should take a DataFetcher instance and return a number. It should use the fetchData method of the DataFetcher to get data.
Loading editor...
typescript