gpt4 book ai didi

reactjs - 如何在 Jest 中模拟 window.alert 方法?

转载 作者:行者123 更新时间:2023-12-03 13:23:18 25 4
gpt4 key购买 nike

我有以下 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": ""
};
}
}

以及相关测试:

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!
});
});

在该表单中,当单击按钮时,它只是使用 alert 发出警报消息。

现在,当我运行测试时,我得到:

expect(received).toBe(expected) // Object.is equality

Expected: 1
Received: 0

这是一个失败,因为模拟显然没有被调用。但我向您保证,当单击表单组件的按钮时,它会发出一条消息。

我怀疑,由于某些原因,当使用 enzyme 以编程方式执行点击时,模拟的 window.alert 不会被 Form 组件使用。

有人吗?

最佳答案

在 Jest 配置中使用 JSDOM global.window === global,因此可以在 window 上模拟它。

最好像这样 mock 它

jest.spyOn(window, 'alert').mockImplementation(() => {});

因为window.alert = jest.fn() 污染了该套件中的其他测试。

黑盒测试的问题是故障排除更加困难,并且依赖真实 DOM 预期的行为也可能会导致问题,因为 Enzyme 不一定支持这种行为。目前尚不清楚实际问题 handleSubmit 是否被调用,alert 模拟未调用只是出现问题的证据。

在这种情况下,按钮上的 click 事件不会导致父表单上的 submit 事件,因为 Enzyme doesn't support that by design .

正确的单元测试策略是为除测试单元(即提交事件处理程序)之外的所有单元设置 spy 或模拟。它通常涉及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(...);

应直接使用 formWrapper.setState 更改状态,而不是模拟 DOM 事件。

一个更独立的单元测试是断言 form 提供了预期的 onSubmit 属性并调用 formWrapper.instance()._handleSubmit(... )直接

关于reactjs - 如何在 Jest 中模拟 window.alert 方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53611098/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com