Hone logo
Hone
Problems

Testing Factory Functions in TypeScript with Jest

Factory functions are a powerful pattern for creating objects with configurable properties, promoting code reusability and encapsulation. This challenge focuses on writing unit tests for TypeScript factory functions using Jest, ensuring they produce the expected objects with the correct configurations. Successfully completing this challenge demonstrates understanding of factory function design and robust testing practices.

Problem Description

You are tasked with creating and testing factory functions in TypeScript. These factory functions will be responsible for creating different types of Product objects based on provided configurations. You need to write Jest tests to verify that these factory functions correctly instantiate Product objects with the specified properties.

What needs to be achieved:

  1. Define a Product interface with properties id: string, name: string, and price: number.
  2. Create two factory functions: createStandardProduct and createDiscountedProduct.
    • createStandardProduct should accept id: string, name: string, and price: number as arguments and return a Product object with these values.
    • createDiscountedProduct should accept id: string, name: string, and price: number as arguments. It should return a Product object with the same values, but also with an additional property discountApplied: boolean set to true.
  3. Write Jest tests to verify that both factory functions:
    • Return a Product object that conforms to the Product interface.
    • Set the id, name, and price properties correctly based on the input arguments.
    • createDiscountedProduct correctly sets discountApplied to true.

Key Requirements:

  • Use TypeScript for both the factory functions and the tests.
  • Utilize Jest for unit testing.
  • Ensure the tests cover both factory functions and their expected behavior.
  • Adhere to good testing practices (e.g., clear test descriptions, assertions).

Expected Behavior:

The tests should pass if the factory functions correctly create Product objects with the specified properties and values. Any discrepancies between the expected and actual object properties should result in test failures.

Edge Cases to Consider:

  • While not explicitly required, consider how you might handle invalid input (e.g., negative prices) in a real-world scenario. For this challenge, assume the input will always be valid.

Examples

Example 1:

Input: createStandardProduct("123", "Laptop", 1200)
Output: { id: "123", name: "Laptop", price: 1200 }
Explanation: The factory function creates a standard product with the provided ID, name, and price.

Example 2:

Input: createDiscountedProduct("456", "Mouse", 25)
Output: { id: "456", name: "Mouse", price: 25, discountApplied: true }
Explanation: The factory function creates a discounted product with the provided ID, name, and price, and sets the discountApplied flag to true.

Example 3: (Edge Case - Testing for the presence of discountApplied)

Input: createDiscountedProduct("789", "Keyboard", 75)
Output: { id: "789", name: "Keyboard", price: 75, discountApplied: true }
Explanation:  Verifies that the `discountApplied` property is present and set to `true` when using the `createDiscountedProduct` factory.

Constraints

  • The Product interface must be defined.
  • The factory functions must accept string and number arguments.
  • The tests must use Jest assertions to verify the object properties.
  • The solution must be written in TypeScript.

Notes

  • Think about how to structure your tests to be readable and maintainable.
  • Consider using Jest's expect object to make assertions about the created objects.
  • Focus on testing the behavior of the factory functions, not the internal implementation details. This promotes flexibility and allows for future refactoring without breaking the tests.
  • You can use toEqual or toStrictEqual for comparing objects in your tests. toEqual performs a deep comparison, while toStrictEqual also checks for the same object identity.
Loading editor...
typescript