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

React复制组件setTimeout逻辑导致分支覆盖率不足,如何编写测试覆盖

问题原因

你当前的测试没有触发setTimeout内部的回调函数,测试执行完成时5秒倒计时还没到,这部分代码从未运行,所以覆盖率统计未达标。

解决方案

使用Jest提供的假定时器能力,在测试中快进时间触发回调执行即可,修改测试代码如下:
首先在describe块新增定时器初始化和清理逻辑:

describe('A component test', () => {
  const props = {
    text: 'mock',
  };

  // 每个测试用例前启用假定时器
  beforeEach(() => {
    jest.useFakeTimers();
  });

  // 每个测试用例后恢复真实定时器,清理mock
  afterEach(() => {
    jest.useRealTimers();
    jest.clearAllMocks();
  });

  // 修改后的复制成功测试用例
  it('should copy to clipboard as expected', async () => {
    const mockWriteText = jest.fn().mockResolvedValueOnce();
    Object.defineProperty(navigator, 'clipboard', {
      configurable: true,
      value: {
        writeText: mockWriteText,
      },
    });
    const renderedModule = mount(<A {...props} />);
    renderedModule.find('button').simulate('click');

    // 等待复制成功的异步逻辑执行完成
    await Promise.resolve();
    expect(mockWriteText).toBeCalledTimes(1);
    // 原用例中'expectedCopy'和props的'mock'不一致,按需修改即可
    expect(mockWriteText).toHaveBeenCalledWith(props.text);

    // 快进所有定时器,触发setTimeout回调
    jest.runAllTimers();
    renderedModule.update();

    // 可选:如果组件有渲染copyStatus对应的提示,可加断言验证状态已重置
    // 示例:expect(renderedModule.text()).not.toContain('复制成功')
  });

  // 修改后的复制失败测试用例
  it('should throw error on attempt to copy to clipboard', async () => {
    const mockWriteText = jest.fn().mockRejectedValue(new Error());
    Object.defineProperty(navigator, 'clipboard', {
      configurable: true,
      value: {
        writeText: mockWriteText,
      },
    });
    // 原用例组件名写错了,是A不是CopyLink
    const renderedModule = mount(<A {...props} />);
    renderedModule.find('button').simulate('click');

    await Promise.resolve();
    expect(mockWriteText).toBeCalledTimes(1);
    // 注意:原组件没有渲染div.error的逻辑,这个断言需要补全组件渲染逻辑后保留,或者修改为验证copyStatus状态
    // 示例:expect(renderedModule.state('copyStatus')).toEqual('no')
  });
});

额外注意

你的原组件返回逻辑有错误,CopyBtn是组件定义没有执行,实际运行会报错,需要修改为:

// 原错误写法
return (<div>
  {CopyBtn}
</div>);

// 修改后
return (<div>
  <CopyBtn />
</div>);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 10:48:04