模拟反应参考值的当前值以进行浅层测试

问题描述 投票:2回答:2

我试图模拟this.ref.current.value作为我的React组件中的函数测试的一部分。目前current为null,因为我正在对我的组件进行浅层安装。我试图找到一种方法来模拟current.value为我的参数返回的内容,以便我可以测试函数的另一部分,refs值对于此测试而言实际上并不重要。

实际功能:

copyDefinitionTarget = selectedInput => () => {
    // get and select the input value
    const copyText = this[`${selectedInput}`].current.value;

    // copy to clipboard
    navigator.clipboard.writeText(copyText);
  };

测试代码:

it('calls navigator.clipboard appropriately to copy the text in copyDefinitionTarget', () => {
    component = shallow(<Alert {...props} />);

    component
      .dive()
      .find('Item')
      .dive()
      .find('Button')
      .simulate('click');

    expect(navigator.clipboard.writeText).toHaveBeenCalled();
  });

测试失败:

TypeError: Cannot read property 'value' of null

      50 |     // get and select the input value
    > 51 |     const copyText = this[`${selectedInput}`].current.value;

有没有办法做到这一点?我关心的是测试navigator.clipboard被调用的不是它的调用。

更新,因为我已经改变我的代码使用this.ref而不是stringRefName实际功能:

copyDefinitionTarget = selectedInput => () => {
    // get and select the input value
    const copyText = selectedInput.current.value;
    // copy to clipboard
    navigator.clipboard.writeText(copyText);
  };

测试代码:

it('calls navigator.clipboard appropriately to copy the text in copyDefinitionTarget', () => {
    component = shallow(<Alert {...props} />);
instance = component.instance();

    // we are clicking on the first Alert Item
    // so mock that ref specifically
    instance.firstNameRef = {
      current: {
        value: 'stuff'
      }
    };

    component
      .dive()
      .find('Item')
      .dive()
      .find('Button')
      .simulate('click');

    expect(navigator.clipboard.writeText).toHaveBeenCalled();
  });

功能调用:

<Item
 inputRef={this.firstNameRef}
 inputValue={`${realmName}`}
 copyDefinitionTarget={this.copyDefinitionTarget(this.firstNameRef)}
/>
javascript reactjs jestjs enzyme ref
2个回答
3
投票

你可以继续做这样的事情:

const component = shallow(<Alert {...props} />);
const selectedInput = 'ref';
component.instance()[selectedInput] = {
  current: {
    value: 'stuff'
  }
}
navigator.clipboard = {writeText: jest.fn()}
component
  .dive()
  .find('Item')
  .dive()
  .find('Button')
  .simulate('click');
expect(navigator.clipboard.writeText).toHaveBeenCalled();

注意:我不确定selectedInput应该是什么类型的字符串,您可以根据您的实际组件代码传递任何适当的字符串。

由于ref作为组件的实例属性存在,只要它看起来像current.value就可以传递任何你想要的对象,然后你可以用模拟替换copy函数,模拟点击然后看看是否调用了writeText


0
投票

如果您传递的是实际的ref而不是字符串,则可以采用另一种方法。我把ref中的值从它自己的函数中拉出来并在我的测试中嘲笑它

实际代码:

  // get the value from ref
  getRefValue = ref => ref.current.value;

  // copy value
  copyDefinitionTarget = selectedInput => () => {
    // get and select the input value
    const copyText = this.getRefValue(selectedInput);
    // copy to clipboard
    navigator.clipboard.writeText(copyText);
  };

测试代码:

it('calls navigator.clipboard appropriately to copy the text in copyDefinitionTarget', () => {
    component = shallow(<MetadataAlert {...props} />);
    instance = component.instance();

    jest.spyOn(instance, 'getRefValue').mockImplementationOnce(() => '💻');

    component
      .dive()
      .find('Item')
      .dive()
      .find('Button')
      .simulate('click');

    expect(navigator.clipboard.writeText).toHaveBeenCalled();
  });
© www.soinside.com 2019 - 2024. All rights reserved.