【问题标题】:ReactJS: How to test for a ref?ReactJS:如何测试参考?
【发布时间】:2018-01-01 12:09:56
【问题描述】:

这是一个在 react 组件中使用的函数。如您所见,我使用 ref 将焦点放在另一个组件的特定输入元素上。

myFunction (param) {
  this.refInput && this.refInput.focus()
}

现在我想通过 jestJS 测试 focus() 是否已被调用。

it('myFunction() should call focus()', () => {
  // SETUP
  const refInput = { focus: jest.fn() }
  wrapper = shallow(<Example
    refInput={refInput}
  />)
  // EXECUTE
  wrapper.instance().myFunction('anything')
  // VERIFY
  expect(refInput.focus).toHaveBeenCalled()
})

但这是错误的,因为我将 refInput 作为属性传递。但它不是this.props.refInput,所以这个尝试行不通。

如何在我的测试中设置 ref?


更新

这是我的组件的样子:

class Example extends Component {
  setStep (state) {
    state.term = ''
    this.setState(state)
    this.refInput && this.refInput.focus()
  }

  render () {
    return (
      <div>
        <Step onClick={this.setStep.bind(this, this.state)}>
          <Step.Content title='title' description='description' />
        </Step>
        <Input ref={input => { this.refInput = input }} />
      </div>
    )
  }
}

【问题讨论】:

  • 浅渲染不维护内部实例,因此它不能保存引用。我认为为了测试 ref 你必须安装组件。看看 MountedRenderer
  • 你使用的是哪个版本的 react?如果是 15.4.0 或更高版本,请查看:reactjs.org/blog/2016/11/16/…。如果你明确想要测试 DOM 节点,你必须使用 Enzime (airbnb.io/enzyme/docs/api/ReactWrapper/ref.html)
  • @MarouenMhiri 我正在使用 React 16 和 Enzyme...

标签: javascript reactjs unit-testing jestjs


【解决方案1】:

尝试做这样的事情:

it('myFunction() should call focus()', () => {
  // SETUP
  wrapper = mount(<Example />)
  // EXECUTE
  wrapper.instance().myFunction('anything')
  // VERIFY
  const elem = wrapper.find('#foo'); 
  const focusedElement = document.activeElement;
  expect(elem.matchesElement(focusedElement)).to.equal(true);
})

注意事项:

  1. 使用 Mount 而不是 Shallow,正如 @Marouen Mhiri 评论的那样,浅层渲染不能容纳 ref

  2. 不需要把 ref 作为 props 传递(其实是错的)

  3. 在我有 wrapper.find('#foo') 的地方,用 Input 中 DOM 元素的 class/id 替换 foo

【讨论】:

  • 我了解您的代码,但在我的情况下,输入元素无法通过 ID 识别。它只有一个类,因为需要很多这样的元素。这就是我使用 refs 的原因。
  • 当然,在那种情况下使用 wrapper.find('.yourClass'),我明白你说这个类有很多元素,但我们可以假设每个 ?因为我们是在已安装组件的上下文中找到的
  • 可以贴出组件的渲染方法吗?只是为了看看它的结构
  • 在这种情况下,我们可以用 Input 组件中的 dom 元素的 class/id 替换 #foo 吗?
  • 是的,我想我们可以添加一个类
猜你喜欢
  • 2019-02-25
  • 1970-01-01
  • 2022-06-13
  • 2021-12-31
  • 1970-01-01
  • 2018-08-03
  • 2015-08-19
  • 2018-09-03
  • 1970-01-01
相关资源
最近更新 更多