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

如何在jest和@testing-library/react中测试catch代码分支?

单元测试覆盖catch分支的实现方法

要触发resetForm的catch分支,只需要让try代码块内的任意一行同步代码抛出错误即可,以下是两种可落地的测试方案,适配你当前使用的jest 24.9.0 + @testing-library/react 12.1.2版本:


方案1:Mock ref方法主动抛错(最推荐,场景可控)

我们可以主动让someRef.current.resetFormValues调用时抛出错误,精准触发catch分支,测试步骤如下:

  • 提前在测试用例的DOM中插入id="errorDisplayDiv"的元素,避免后续DOM操作提前抛错干扰测试预设
  • MocksetStateAndLogError方法,用于验证catch分支是否被执行
  • MocksomeRef的resetFormValues方法,让其调用时主动抛出自定义错误
  • 渲染组件后触发Reset按钮的点击事件
  • 断言setStateAndLogError被正确调用,且入参为我们抛出的错误实例

测试代码示例:

import { render, fireEvent } from '@testing-library/react';
import MyComponent from './MyComponent';
import { setStateAndLogError } from './your-module-path';

//  mock要验证的catch分支执行方法
jest.mock('./your-module-path', () => ({
  ...jest.requireActual('./your-module-path'),
  setStateAndLogError: jest.fn()
}));

test('resetForm catch分支被正确覆盖', () => {
  // 提前插入错误提示DOM
  const errorDiv = document.createElement('div');
  errorDiv.id = 'errorDisplayDiv';
  document.body.appendChild(errorDiv);

  // 自定义错误,用于后续断言
  const mockError = new Error('测试触发表单重置错误');
  // 若someRef是组件props传入则直接传递mock值,若是内部绑定子组件则mock对应子组件的resetFormValues方法即可
  const mockRef = {
    current: {
      resetFormValues: jest.fn(() => {
        throw mockError;
      })
    }
  };

  const { getByText } = render(<MyComponent someRef={mockRef} />);
  
  // 触发重置按钮点击
  fireEvent.click(getByText('Reset'));

  // 验证catch分支逻辑执行
  expect(setStateAndLogError).toHaveBeenCalledTimes(1);
  expect(setStateAndLogError).toHaveBeenCalledWith(mockError);

  // 清理测试插入的DOM
  document.body.removeChild(errorDiv);
});

方案2:DOM缺失触发报错(无需mock ref,实现简单)

如果不想mock ref相关逻辑,可以直接不在测试环境插入id="errorDisplayDiv"的元素,此时document.getElementById("errorDisplayDiv")会返回null,执行div.innerHTML时会自动抛出Cannot set properties of null (setting 'innerHTML')的错误,直接进入catch分支:

import { render, fireEvent } from '@testing-library/react';
import MyComponent from './MyComponent';
import { setStateAndLogError } from './your-module-path';

jest.mock('./your-module-path', () => ({
  ...jest.requireActual('./your-module-path'),
  setStateAndLogError: jest.fn()
}));

test('resetForm catch分支在DOM缺失时触发', () => {
  // 确保当前DOM中没有id为errorDisplayDiv的元素
  expect(document.getElementById('errorDisplayDiv')).toBeNull();

  const mockRef = {
    current: {
      resetFormValues: jest.fn() // 这里不用抛错
    }
  };

  const { getByText } = render(<MyComponent someRef={mockRef} />);
  fireEvent.click(getByText('Reset'));

  expect(setStateAndLogError).toHaveBeenCalledTimes(1);
  expect(setStateAndLogError).toHaveBeenCalledWith(expect.any(Error));
});

额外注意事项

  • 如果someRef是组件内部声明的未对外暴露的ref,你可以通过jest.mock来mock ref绑定的子组件,让子组件的resetFormValues方法抛错即可
  • @testing-library/react 12版本完全兼容fireEvent事件触发写法,无需额外安装其他依赖

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 17:54:03