无法在 React 组件中测试提交处理程序
Can't test submit handler in React component
我正在尝试为我的组件测试事件,但没有调用提交处理程序。除了事件之外,我所有的单元测试都在工作。我正在使用 Tape、Sinon 和 JSDOM,并在网上四处寻找有类似问题的人。有一个类似问题的 Github 问题,但我不是 100% 确定它是否完全相同。 https://github.com/facebook/react/issues/1185
SO 上还有一个相关的 ,但它没有帮助,因为他们使用的是浅渲染。
测试:
// 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 = '';
}
看看这个 React Reusable Components 其中说:
No Autobinding
Methods follow the same semantics as regular ES6 classes, meaning that they don't automatically bind this to the instance. You'll have to explicitly use .bind(this) or arrow functions =>.
并尝试将您的 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>
@GilesB 谢谢你,我在回复之前应该先问清楚。
添加圆括号对我有用:
// Render the DOM
output = renderDOM(
<ToDoCreate
onSubmit={onSubmitHandler()}
/>,
document.body);
我正在尝试为我的组件测试事件,但没有调用提交处理程序。除了事件之外,我所有的单元测试都在工作。我正在使用 Tape、Sinon 和 JSDOM,并在网上四处寻找有类似问题的人。有一个类似问题的 Github 问题,但我不是 100% 确定它是否完全相同。 https://github.com/facebook/react/issues/1185
SO 上还有一个相关的
测试:
// 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 = '';
}
看看这个 React Reusable Components 其中说:
No Autobinding
Methods follow the same semantics as regular ES6 classes, meaning that they don't automatically bind this to the instance. You'll have to explicitly use .bind(this) or arrow functions =>.
并尝试将您的 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>
@GilesB 谢谢你,我在回复之前应该先问清楚。 添加圆括号对我有用:
// Render the DOM
output = renderDOM(
<ToDoCreate
onSubmit={onSubmitHandler()}
/>,
document.body);