React 中的模拟子组件

Mock child component in React

有没有一种干净的方法可以在使用 Mocha 和朋友对元素进行单元测试时模拟子元素?

例如,假设我有这样的东西:

<Parent>
  <Child aProp={ this.props.clickChild() }/>
</Parent>

我想模拟它,这样我就可以手动触发 aProp,然后告诉它调用了我传递给它的 clickChild

经过大量研究,这似乎不太可能。如果您以非常特定的格式执行它们,则可以使用某些模拟的东西,但是您必须做几件在 "real" 代码中不符合标准的事情。我不喜欢为测试修改代码。

我已经确定的替代方案是针对某些情况,我会在 mount() 之后找到元素,获取提供回调的 属性,然后直接触发它,然后做任何我需要的事。不是一个完美的通用方案,但它有效。

拿这个例子代码来说:

// Parent.js
export default class Parent extends React.Component {
    doSomething() {
        this.props.doSomethingTriggered();
    }

    render() {
        return <div>
            <Child onClick={ this.doSomething.bind() }/>
        </div>;
    }
}

我可以使用 enzyme 来挂载组件,然后触发 ChildonClick 属性 并监视我给它的回调以确保它被正确调用。

 it('should do something', () => {
      const callback = sinon.spy(() => {});
      const wrapper = mount(<Parent doSomethingTriggered={ callback }/>);
      wrapper.find(Child).props().onClick();
      sinon.assert.calledOnce(callback);
 });

不是很嘲讽,但在某些情况下确实让我绕过了一大块依赖代码。


由于这是一个热门问题,因此可以更新 Enzyme 16。您现在可以在任何元素上调用 instance(),然后直接调用其函数。

例如,举这些例子:

class Parent extends React.Component {
  render() {
    return <div><Child /></div>
  }
}

class Child extends React.Component {
  render() { return <div>Hi</div> }

  doSomething() { }
}

使用酶 16,您现在可以:

mount(<Parent />).find(Child).instance().doSomething()