对于contentEditable元素,“onInput”上未满足Expect方法

时间:2016-06-02 14:47:01

标签: reactjs sinon chai enzyme sinon-chai

我有一个使用contentEditable作为输入法的组件。感兴趣组件的部分是:

<div className="enter-edit-mode" onClick={view.enterEditMode}>
    <div className="user-input" ref="content" contentEditable onInput={view.textChanged}></div>
</div>

该组件工作正常 - 它进入用户输入的textChanged方法。该方法如下所示:

textChanged: function (e) {
    var view      = this,
        textValue = e.target.innerHTML;

    view.setState({
        enteringText: textValue.length,
        temporaryValue: textValue
    });
}
当我尝试测试输入行为时,

我正面临的问题出现。设置使用 chai sinon 完成。我正在使用一个简单的renderComponent函数渲染组件,使用酶的mount方法。

beforeEach(function () {
    view = renderComponent(card);
    viewReact = view.get(0);
});

it('should enter text changed method on input', function () {
    let spy = sinon.spy(viewReact, 'textChanged');
    view.find('.user-input').simulate('input');
    expect(spy).to.have.been.called;
    spy.restore();
});

它输出预期的textChanged至少被调用一次,但它从未被调用奇怪的部分是,如果我在组件的方法中放置console.log,它就会到达那里。

我试图让它发挥作用

  • 使用sinon.stub代替spy,因为我的方法可能无法正常使用
  • 使用view.find('.user-input').simulate('input', {target: {value: "lorem"}).simulate('input', {key: 'a'})
  • 进行调用

如果不是模拟输入而是viewReact.textChanged(),它显然有效。

我猜测它是contentEditable的输入方法导致了这个问题。有什么建议?如何在onInput方法中正确输入文字? (即使它进入textChanged方法,文本为空)

2 个答案:

答案 0 :(得分:1)

我可以重现您的问题,尝试测试以下组件(看起来与您的类似):

<div class="col-lg-4 col-md-4 col-sm-6 col-xs-12">
       Your content here
</div>

我还设法以一种有点复杂的方式让测试工作:

const MyComponent = React.createClass({
  textChanged(e) { console.log('text changed') },
  render() {
    return (
      <div className="enter-edit-mode">
        <div className="user-input" ref="content" contentEditable onInput={ this.textChanged }></div>
      </div>
    );
  }
});

这个组件的it('should enter text changed method on input', () => { let view = mount(<MyComponent/>); let spy = sinon.spy(view.instance(), 'textChanged'); view = view.mount(); view.find('.user-input').simulate('input'); expect(spy).to.be.called; spy.restore(); }); re-mount似乎可以解决这个问题。

我根本不熟悉Enzyme(尽管我喜欢它:),但看起来它在组件周围添加了各种层,在这种情况下,Sinon间谍很容易“丢失”。

一个可能的警告:我使用view.mount()在Node中进行了所有这些测试,而不是在浏览器中。

答案 1 :(得分:0)

我做了一点测试,我没有sinon但是我发现了一个用例:

class Home extends Component {

  state = {
    status: 'default'
  }

  textChanged = () => {
    this.setState({
      status: 'changed'
    })
  }

  render () {
    return (
        <div className="enter-edit-mode" >
          <div className="user-input" ref="content" contentEditable onInput={this.textChanged}>Hello</div>
          <span>{this.state.status}</span>
        </div>
    )
  }
}

和测试

describe('component', () => {
    it('should say changed', () => {
      const component = shallow(<Home />);

      expect(component.find('span').text()).toEqual('default');

      component.find('.user-input').simulate('input', {key: 'a'})

      expect(component.find('span').text()).toEqual('changed');
    });
});

它通过所有预期