You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何测试React Context内部函数?寻求测试覆盖方案

测试React BottomBarContext中的handleClickMenu函数

要覆盖handleClickMenu函数的测试,你需要通过消费Context来调用该函数,并验证它的三个核心行为:更新选中菜单、调用pushBackRoute工具函数、触发路由跳转。以下是具体实现步骤:

步骤1:Mock外部依赖函数

pushBackRoute是外部导入的工具函数,需要在测试中Mock它,方便验证调用情况:

jest.mock('../libs/helpers/backRouteHelper', () => ({
  pushBackRoute: jest.fn()
}));

步骤2:编写测试用的Context消费组件

创建一个简单组件来消费BottomBarContext,暴露调用handleClickMenu的入口,同时展示当前选中的菜单状态:

import { useContext } from 'react';
import { BottomBarContext } from './BottomBarContext';

const TestConsumer = () => {
  const { handleClickMenu, selectedMenu } = useContext(BottomBarContext);
  return (
    <div>
      <span data-testid="selected-menu">{selectedMenu}</span>
      <button 
        data-testid="trigger-menu-click"
        onClick={() => handleClickMenu({ name: 'Riwayat', route: '/marketplace/history' })}
      >
        触发菜单点击
      </button>
    </div>
  );
};

步骤3:完善测试用例

整合上述内容,编写完整测试用例,覆盖handleClickMenu的所有逻辑:

/* eslint-disable jest/prefer-called-with */
import { render, screen, fireEvent } from '@testing-library/react';
import { BottomBarProvider } from './BottomBarContext';
import { useContext } from 'react';
import { BottomBarContext } from './BottomBarContext';
import '@testing-library/jest-dom/extend-expect';
import { pushBackRoute } from '../libs/helpers/backRouteHelper';

const mockHistoryPush = jest.fn();
jest.mock('react-router-dom', () => ({
  ...jest.requireActual('react-router-dom'),
  useLocation: () => ({
    pathname: '/marketplace'
  }),
  useHistory: () => ({
    push: mockHistoryPush
  })
}));

// Mock外部工具函数
jest.mock('../libs/helpers/backRouteHelper', () => ({
  pushBackRoute: jest.fn()
}));

// 测试用Context消费组件
const TestConsumer = () => {
  const { handleClickMenu, selectedMenu } = useContext(BottomBarContext);
  return (
    <div>
      <span data-testid="selected-menu">{selectedMenu}</span>
      <button 
        data-testid="trigger-menu-click"
        onClick={() => handleClickMenu({ name: 'Riwayat', route: '/marketplace/history' })}
      >
        触发菜单点击
      </button>
    </div>
  );
};

describe('BottomBarProvider', () => {
  beforeEach(() => {
    // 重置所有mock调用记录,避免测试用例间干扰
    jest.clearAllMocks();
  });

  it('should render children correctly', () => {
    const children = <div data-testid="children">Hello, World!</div>;
    render(<BottomBarProvider>{children}</BottomBarProvider>);
    expect(screen.getByTestId('children')).toHaveTextContent('Hello, World!');
  });

  it('should update selectedMenu, call pushBackRoute and trigger history push when handleClickMenu is called', () => {
    // 渲染Provider和测试消费组件
    render(
      <BottomBarProvider>
        <TestConsumer />
      </BottomBarProvider>
    );

    // 验证初始选中菜单
    expect(screen.getByTestId('selected-menu')).toHaveTextContent('Belanja');

    // 触发菜单点击事件
    fireEvent.click(screen.getByTestId('trigger-menu-click'));

    // 验证选中菜单已更新
    expect(screen.getByTestId('selected-menu')).toHaveTextContent('Riwayat');

    // 验证pushBackRoute被正确调用
    expect(pushBackRoute).toHaveBeenCalledWith('/marketplace');

    // 验证路由跳转被触发
    expect(mockHistoryPush).toHaveBeenCalledWith('/marketplace/history');
  });
});

关键说明

  • 通过测试消费组件,直接访问并触发Context中的handleClickMenu函数,实现逻辑覆盖。
  • 每次测试前重置Mock调用记录,确保测试独立性。
  • 分别验证handleClickMenu的三个核心行为,确保函数逻辑完全符合预期。

内容的提问来源于stack exchange,提问作者Faishal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 15:30:45