无法在React组件中测试提交处理程序

时间:2015-12-14 11:11:44

标签: javascript unit-testing reactjs tdd sinon

我正在尝试为我的组件测试事件,而我没有调用提交处理程序。除了事件之外,我的所有单元测试都在工作。我正在使用Tape,Sinon和JSDOM,并在网上搜索了很多有类似问题的人。对于类似的问题存在Github问题,但我不能100%确定它是否完全相同。 https://github.com/facebook/react/issues/1185 这里还有一个相关的post,但它没有帮助,因为他们使用的是浅层渲染。

测试

// Create a document using JSDOM
const document = createDocument();

let output;

const onSubmitHandler = spy();

// Render the DOM
output = renderDOM(
  <ToDoCreate
    onSubmit={onSubmitHandler}
  />,
document.body);

const form = TestUtils.findRenderedDOMComponentWithTag(output, 'form');

// Simulate a submit
TestUtils.Simulate.submit(form);

const actual   = onSubmitHandler.callCount;
const expected = 1;

// Test the event handler was called
assert.equal(actual, expected);
assert.end();

结果:

# ToDoCreate component
# ...submitted form to create a ToDo
not ok 14 should be equal
---
operator: equal
expected: 1
actual:   0
...

有没有人对为什么这不起作用有任何想法?

由于

更新:添加ToDoCreate的render()输出

<form className={toDoCreateClasses} onSubmit={this._handleToDoCreateSubmit}>
  <div className="form-group">
    <label className="sr-only">New ToDo</label>
    <input type="text" className="form-control ToDoInput" ref="title" placeholder="Add a new ToDo..." />
  </div>

  <button type="submit" className="btn btn-primary">Add</button>
</form>

更新:添加_handleToDoCreateSubmit方法

_handleToDoCreateSubmit(e) {
  e.preventDefault();

  // Get the ToDo title
  let title = this.refs.title.value;

  // Validate
  if ( title === '' ) {
    window.alert('You need to enter a ToDo first :)');
    return false;
  }

  // Trigger the submit event
  ToDoDispatcher.dispatch({
    actionType: 'TODO_CREATE_SUBMIT',
    title:      title
  });

  // Clear the Dom node
  this.refs.title.value = '';
}

2 个答案:

答案 0 :(得分:1)

@GilesB感谢你,我应该在回答之前询问。 添加圆括号对我有用:

// Render the DOM
   output = renderDOM(
     <ToDoCreate
     onSubmit={onSubmitHandler()}
   />,
   document.body);

答案 1 :(得分:0)

看看这个React Reusable Components,其中说:

  

没有自动装订
  方法遵循与常规ES6类相同的语义,这意味着它们不会自动将其绑定到实例。您必须明确使用.bind(this)或arrow functions =&gt;。

并尝试使用:

更改render()
            <form className={""} onSubmit={this._handleToDoCreateSubmit.bind(this)}>
            <div className="form-group">
                <label className="sr-only">New ToDo</label>
                <input type="text" className="form-control ToDoInput" ref="title" placeholder="Add a new ToDo..." />
            </div>

            <button type="submit" className="btn btn-primary">Add</button>
        </form>