如何从不直接处理状态管理的 reactstrap 为 UncontrolledTooltip 创建单元测试?

How to create an unit test for UncontrolledTooltip from reactstrap that does not handle state management directly?

我从 reactstrap 实现了简单的 UncontrolledTooltip。文档 (https://reactstrap.github.io/components/tooltips/) 说

uncontrolled component can provide the functionality wanted without the need to manage/control the state of the component

如果我想实施一个单元测试(例如 jest + enzyme)来测试它的状态是打开还是关闭,我如何在不手动修改状态值的情况下创建单元测试?这有可能实现吗?似乎只有常规 Tooltip 组件才有可能,但我喜欢听取经验丰富的工程师的建议。

[更新]:

根据要求,我在此处包含了工具提示和我正在尝试执行的单元测试。目前,我想在工具提示上模拟 hover 但是 mockHover.mock.calls.length returns 因为 0 我解释为模拟函数没有被触发。

这是我的工具提示。

import React from 'react';
import { UncontrolledTooltip } from 'reactstrap';    

export default class MyTooltip extends React.Component {
  render() {
    const { metaData, wg } = this.props;
    return (
      <div>
        <UncontrolledTooltip placement="bottom" trigger={'hover'} target={wg}>
          {metaData}
        </UncontrolledTooltip>
      </div>
    );
  }
}

这是我使用 jest and enzyme:

的单元测试
describe('<MyTooltip />', () => {
  it('Tooltip unit test', () => {    
    const mockHover = jest.fn();
    const wrapper = shallow(<MyTooltip trigger={mockHover} />);
    expect(wrapper.find(UncontrolledTooltip));
    wrapper.find(UncontrolledTooltip).simulate('hover');
    expect(mockHover.mock.calls.length).toEqual(1);
  });
});    

有几件重要的事情可以开始:

  1. UncontrolledTooltip 是第 3 方包的一部分,因此您不会对其进行显式测试。 相反,您最好专注于围绕 UncontrolledTooltip.
  2. 测试包装器
  3. simulate 与事件浏览器系统无关。 props().onHover(...) 只是一个语法糖。因此,如果目标组件有这样的 prop - 它是 callback-function - 它将被调用。如果没有这样的道具 - 这将取决于 defaultProps 发生了什么。反正一点也不像 'emulating mouse cursor over the element'.
  4. shallow() 将在 UncontrolledTooltip 级别停止渲染(不会渲染其内部结构)

牢记这一点,我认为你只能:

  1. 您的组件最终呈现 UncontrolledTooltip 具有预期的常量 prop 值
  2. metaDatawg 属性都传递给 UncontrolledTooltip

    it('renders UncontrolledTooltips under the hood', () => {
      const wg = '1';
      const metaData = (<span>2</span>);
      const wrapper = shallow(<MyTooltip wg={wg} metaData={metaData} />);
      const innerTooltip = wrapper.find(UncontrolledTooltip);
      /* 
      I don't validate `find(UncontrolledTooltip).toHaveLength(1)`
      since assertion on `.find(..).props()` would throw exception otherwise
      */ 
      expect(innerTooltip.props().placement).toEqual('bottom');
      expect(innerTooltip.props().trigger).toEqual('hover');
      expect(innerTooltip.props().wg).toEqual(wg);
      expect(innerTooltip.props().metaData).toEqual(metaData);
    });