nou*_*ine 4 reactjs jestjs enzyme
我有以下React组件:
class Form extends React.Component {
constructor(props) {
super(props);
this.state = this._createEmptyTodo();
}
render() {
this.i18n = this.context;
return (
<div className="form">
<form onSubmit={this._handleSubmit.bind(this)}>
<input
placeholder={this.i18n.placeholders.addTitle}
type="text"
value={this.state.title}
onChange={this._handleTitleChange.bind(this)}></input>
<textarea
placeholder={this.i18n.placeholders.addDescription}
value={this.state.description}
onChange={this._handleDescriptionChange.bind(this)}></textarea>
<button>{this.i18n.buttons.submit}</button>
</form>
</div>
);
}
_handleTitleChange(e) {
this.setState({
title: e.target.value
});
}
_handleDescriptionChange(e) {
this.setState({
description: e.target.value
});
}
_handleSubmit(e) {
e.preventDefault();
var todo = {
date: new Date().getTime(),
title: this.state.title.trim(),
description: this.state.description.trim(),
done: false
};
if (!todo.title) {
alert(this.i18n.errors.title);
return;
}
if (!todo.description) {
alert(this.i18n.errors.description);
return;
}
this.props.showSpinner();
this.props.actions.addTodo(todo);
this.setState(this._createEmptyTodo());
}
_createEmptyTodo() {
return {
"pkey": null,
"title": "",
"description": ""
};
}
}
Run Code Online (Sandbox Code Playgroud)
和相关测试:
const i18nContext = React.createContext();
Form.contextType = i18nContext;
describe('The <Form> component', () => {
var wrapper;
var showSpinner;
var actions = {}
beforeEach(() => {
showSpinner = jest.fn();
actions.addTodo = jest.fn();
wrapper = mount(<i18nContext.Provider value={i18n["en"]}>
<Form
showModalPanel={showSpinner}
actions={actions} />
</i18nContext.Provider>);
});
test("validate its input", () => {
window.alert = jest.fn();
wrapper.find("button").simulate("click");
expect(window.alert.mock.calls.length).toBe(1);//<<< this FAILS!
});
});
Run Code Online (Sandbox Code Playgroud)
这种形式,当单击按钮时,仅使用发出警报alert。
现在,当我运行测试时,我得到了:
expect(received).toBe(expected) // Object.is equality
Expected: 1
Received: 0
Run Code Online (Sandbox Code Playgroud)
这是一个失败,因为该模拟显然没有被调用。但是,我向您保证,表单组件在单击其按钮时确实会警告消息。
我怀疑由于某些原因,使用酶以编程方式执行单击时,组件window.alert不会使用该Form模型。
任何人?
相反window,您可以使用global.
global.alert = jest.fn();
Run Code Online (Sandbox Code Playgroud)
这是因为浏览器使用window名称,而nodejs使用global名称。
在带有JSDOM的Jest配置中global.window === global,因此可以对其进行模拟window。
最好像这样嘲笑它
jest.spyOn(window, 'alert').mockImplementation(() => {});
Run Code Online (Sandbox Code Playgroud)
因为会window.alert = jest.fn()污染此套件中的其他测试。
黑盒测试的问题在于,故障排除难度更大,并且还依赖真实DOM预期的行为可能会导致问题,因为酶不一定支持这种行为。不知道实际问题是否handleSubmit被调用,alert未调用模拟仅是发生问题的证据。
在这种情况click下,按钮上的事件不会导致submit父表单上的事件,因为Enzyme 并非设计上支持它。
正确的单元测试策略是为除测试对象(提交事件处理程序)以外的所有单元设置间谍程序或模拟程序。它通常涉及shallow而不是mount。
可能应该是:
jest.spyOn(window, 'alert').mockImplementation(() => {});
const formWrapper = wrapper.find(Form).dive();
jest.spyOn(formWrapper.instance(), '_handleSubmit');
formWrapper.find("form").simulate("submit");
expect(formWrapper.instance()._handleSubmit).toBeCalled();
expect(window.alert).toBeCalledWith(...);
Run Code Online (Sandbox Code Playgroud)
应直接使用formWrapper.setState而不是DOM事件模拟来更改状态。
一个更孤立的单元测试将是断言form所提供的预期onSubmit道具和formWrapper.instance()._handleSubmit(...)直接调用。
| 归档时间: |
|
| 查看次数: |
5143 次 |
| 最近记录: |