乐闻世界logo
搜索文章和话题

How to mock a single state variable in a context provider with jest?

1个答案

1

When using Jest for unit testing, if our components depend on state variables provided by context, we need to ensure that these state variables are properly mocked in the test environment. Here, I'll demonstrate with a concrete example how to mock a single state variable within a React context.

Step 1: Create the Context

First, we create a ThemeContext.

javascript
import React, { createContext, useState, useContext } from 'react'; const ThemeContext = createContext(); export function ThemeProvider({ children }) { const [theme, setTheme] = useState('light'); return ( <ThemeContext.Provider value={{ theme, setTheme }}> {children} </ThemeContext.Provider> ); } export function useTheme() { return useContext(ThemeContext); }

Step 2: Write the Component

Assume we have a simple component that depends on ThemeContext.

javascript
import React from 'react'; import { useTheme } from './ThemeContext'; function Greeting() { const { theme } = useTheme(); return <h1 className={theme}>Hello, world!</h1>; } export default Greeting;

Step 3: Mock the Context for Testing

When testing the Greeting component, we can mock ThemeContext using Jest and @testing-library/react.

javascript
import React from 'react'; import { render } from '@testing-library/react'; import Greeting from './Greeting'; import { ThemeContext } from './ThemeContext'; test('Greeting component receives theme', () => { // Set our mocked context value const themeValue = { theme: 'dark' }; // Mock the `useContext` hook using Jest's `mockImplementation` method jest.spyOn(React, 'useContext').mockImplementation(() => themeValue); const { getByText } = render(<Greeting />); expect(getByText('Hello, world!')).toHaveClass('dark'); });

In this test, we intercept the call to React.useContext using jest.spyOn to ensure it returns our predefined themeValue. This guarantees that regardless of how useTheme invokes useContext, it receives the theme value we've configured for testing purposes.

The advantage of this approach is that we can precisely control the values within the context without rendering the provider component, resulting in faster tests that are isolated from other state changes. This is highly applicable for unit testing.

2024年6月29日 12:07 回复

你的答案