首页 > 解决方案 > 由于超时逻辑,分支覆盖失败

问题描述

我有以下实现,在单击按钮时,一些文本被添加到剪贴板。

5 秒后状态改变,用户可以再次点击按钮进行复制。

逻辑工作正常,并在我有 100% 行覆盖率的地方编写了测试。

但不满足分支和语句覆盖率。经过调查,问题是由于这条线。

setTimeout(() => setCopyStatus(''), 5000);

如果我只是为了测试而将其注释掉,我将获得 100% 的测试覆盖率。

由于我遇到了线路覆盖。无法理解我应该在这里做什么来满足覆盖范围的期望。

我能否获得一些关于如何针对此编写测试以获得分支覆盖率的建议。

这是组件。

import React, { useState } from 'react';
import { Button } from '../../Button';

const A = ({
 text,
}) => {
  const [copyStatus, setCopyStatus] = useState('');

  const sleep = () => {
    // issue is with this line. If I comment this out, I get full coverage.
    setTimeout(() => setCopyStatus(''), 5000);
  };

  const onClick = () => {
    window.navigator.clipboard.writeText(text)
      .then(() => {
        setCopyStatus('yes');
        sleep();
      })
      .catch(() => setCopyStatus('no'));
  };

  const CopyBtn = () => (
    <Button onClick={onClick}>
      Click
    </Button>
  );

  return (<div>
    {CopyBtn}
  </div>);
};

export default A;

这是当前所有通过的测试,但如前所述,不满足分支覆盖率。

import React from 'react';
import { mount } from 'enzyme';
import A from '../../../src/components/A';

jest.mock('../../Button', () => ({
  Button: 'button',
}));

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

  it('should copy to clipboard as expected', () => {
    Object.defineProperty(navigator, 'clipboard', {
      configurable: true,
      value: {
        writeText: jest.fn().mockReturnValueOnce(Promise.resolve()),
      },
    });
    const renderedModule = mount(<A {...props} />);
    renderedModule.find('button').simulate('click');
    expect(navigator.clipboard.writeText).toBeCalledTimes(1);
    expect(navigator.clipboard.writeText).toHaveBeenCalledWith('expectedCopy');
  });

  it('should throw error on attempt to copy to clipboard', () => {
    Object.defineProperty(navigator, 'clipboard', {
      configurable: true,
      value: {
        writeText: jest.fn().mockRejectedValue(new Error()),
      },
    });
    const renderedModule = mount(<CopyLink {...props} />);
    renderedModule.find('button').simulate('click');
    expect(navigator.clipboard.writeText).toBeCalledTimes(1);
    expect(renderedModule.find('div.error').at(0).exists()).toBeTruthy();
  });

  // some other tests where I try without text value other redux tests not related to issue. 
});

标签: javascriptreactjsjestjs

解决方案


推荐阅读