Hone logo
Hone
Problems

Mocking React Context in Jest

Testing components that consume React Context can be challenging because you need to provide a mocked or simplified version of the context for your tests. This challenge focuses on creating a robust way to mock React Context in Jest, enabling you to test components that rely on it without needing a full context provider setup.

Problem Description

You are tasked with creating a utility function that allows you to easily mock React Context for your Jest tests. This utility should accept a mock context value and return a mock context provider component. This provider will wrap your component under test, injecting the specified mock context value. This is useful for isolating components and testing their behavior in isolation, ensuring that their logic works correctly regardless of the actual context's implementation.

Key Requirements:

  • createMockContextProvider function: This function will be the core of the solution. It should take a single argument: mockContextValue.
  • Returns a React Component: The createMockContextProvider function must return a React functional component.
  • Injects Mock Context: The returned component should act as a Provider for a specific (but unspecified, as we're mocking) React Context. When rendered, it should wrap its children and make mockContextValue available to them.
  • Accepts children: The returned provider component must accept and render its children prop.

Expected Behavior:

When a component under test is rendered within the mock provider created by createMockContextProvider, any calls to useContext for the relevant context (which is implicitly mocked by this provider) should resolve to mockContextValue.

Edge Cases:

  • What if mockContextValue is undefined or null? The mock provider should still function correctly and provide these values.
  • The challenge doesn't require you to create the original context, only to mock its provider behavior.

Examples

Example 1:

Input:

A mock context value: { user: { name: 'Alice' } }

Code Snippet (Illustrative - how it would be used in a test):

// Assume this is how you'd create and use your mock provider
import React, { useContext, createContext } from 'react';

// We don't have the *actual* context here, but we'll assume one exists for the test.
// For the purpose of this challenge, you're *only* building the mock provider.

const MockContext = createContext<any>(undefined); // Placeholder for context

function createMockContextProvider(mockContextValue: any) {
  return function MockProvider({ children }: { children: React.ReactNode }) {
    return (
      <MockContext.Provider value={mockContextValue}>
        {children}
      </MockContext.Provider>
    );
  };
}

// In a test file:
const MyComponent = () => {
  const contextValue = useContext(MockContext); // This would ideally be the *real* context hook
  return <div>User: {contextValue.user.name}</div>;
};

const MockProvider = createMockContextProvider({ user: { name: 'Alice' } });

// Render MyComponent within MockProvider
// const { getByText } = render(<MockProvider><MyComponent /></MockProvider>);
// expect(getByText('User: Alice')).toBeInTheDocument();

Output (of the createMockContextProvider function):

A React component that, when rendered, provides { user: { name: 'Alice' } } to its descendants.

Explanation:

The createMockContextProvider function creates a component (MockProvider). When MockProvider is used in a test, it wraps its children (e.g., MyComponent) and provides the specified mockContextValue via a context provider. Any component within MyComponent that consumes MockContext will receive { user: { name: 'Alice' } }.

Example 2:

Input:

A mock context value: null

Code Snippet (Illustrative):

// ... (createMockContextProvider implementation)

const MockProvider = createMockContextProvider(null);

// In a test file:
// const { getByText } = render(<MockProvider>...</MockProvider>);
// This would test a component that gracefully handles a null context.

Output (of the createMockContextProvider function):

A React component that, when rendered, provides null to its descendants.

Explanation:

This demonstrates that the mock provider should handle null values correctly, just as it would handle other JavaScript values.

Constraints

  • The solution must be written in TypeScript.
  • The createMockContextProvider function should accept any type for mockContextValue and return a functional component that correctly types its children prop.
  • No external testing libraries (like @testing-library/react) are required for the implementation of createMockContextProvider itself, but the examples illustrate how it would be used with them. You are only building the createMockContextProvider function.

Notes

  • This challenge focuses on the pattern of creating a mock provider. You do not need to create or import any specific React Context. You can use React.createContext internally within your createMockContextProvider function to establish a context to provide to.
  • Consider how you will handle the type of the mockContextValue and the generic nature of the returned provider component.
  • Think about the structure of a typical React Context Provider component and how you can replicate that minimal functionality.
Loading editor...
typescript