Hone logo
Hone
Problems

Testing Custom React Hooks with Jest

Custom React Hooks are a powerful way to share stateful logic between components. However, testing these hooks directly can be tricky as they are not components themselves and don't render UI. This challenge focuses on how to effectively test custom hooks using Jest and the @testing-library/react-hooks library.

Problem Description

Your task is to write unit tests for a custom React Hook called useCounter. This hook manages a simple counter value, providing functions to increment, decrement, and reset the counter. You will use Jest and @testing-library/react-hooks to test its behavior.

Requirements:

  1. useCounter Hook Implementation (Provided):

    • The hook should accept an optional initial value. If no initial value is provided, it should default to 0.
    • It should return an object containing:
      • count: The current value of the counter.
      • increment: A function that increases count by 1.
      • decrement: A function that decreases count by 1.
      • reset: A function that sets count back to its initial value.
  2. Testing useCounter:

    • Write Jest tests for the useCounter hook.
    • Use @testing-library/react-hooks to render and interact with the hook in your tests.
    • Test the following scenarios:
      • Initial state with no provided value.
      • Initial state with a provided positive value.
      • Incrementing the counter.
      • Decrementing the counter.
      • Resetting the counter to its initial value.
      • Edge case: Decrementing the counter below zero (it should still decrement).

Examples

Example 1: Initial state with default value

Input Hook Call: useCounter()
Expected Output State: { count: 0 }

Explanation: When useCounter is called without an initial value, the count should start at 0.

Example 2: Initial state with a provided value

Input Hook Call: useCounter(10)
Expected Output State: { count: 10 }

Explanation: When useCounter is called with an initial value of 10, the count should start at 10.

Example 3: Incrementing the counter

Input Hook Calls:
1. const { count, increment } = useCounter(5);
2. increment();
3. increment();

Expected Final State: { count: 7 }

Explanation: Starting at 5 and calling increment twice results in a final count of 7.

Example 4: Decrementing and resetting

Input Hook Calls:
1. const { count, decrement, reset } = useCounter(3);
2. decrement();
3. decrement();
4. reset();

Expected Final State: { count: 3 }

Explanation: Starting at 3, decrementing twice to 1, and then calling reset returns the count to its initial value of 3.

Constraints

  • The tests must be written in TypeScript.
  • You must use Jest as the testing framework.
  • You must use the @testing-library/react-hooks library for testing hooks.
  • The provided useCounter hook implementation should be assumed to exist and be correct for the purpose of writing tests. (You will be provided with the hook implementation separately if this were a live challenge, or you can assume it exists for this exercise.)

Notes

  • @testing-library/react-hooks provides a renderHook function that allows you to test hooks in isolation.
  • The renderHook function returns an object with result and rerender properties. result.current gives you access to the latest value returned by your hook.
  • You can simulate user interactions by calling the functions returned by your hook.
  • Consider using waitForNextUpdate if your hook has asynchronous operations (though this specific hook does not).
  • Focus on testing the behavior of the hook's returned values and functions.
Loading editor...
typescript