![](/img/trans.png)
[英]React Testing Library jest.fn() toHaveBeenCalled() not working
[英]Jest.fn() not working in React unit-test
我正在测试一个名为handleSubmit
的组件方法(名称无关紧要......)。
// ...imported all modules at the top, including enzyme
it('should submit form data', () => {
let form = shallow(<Form />);
let handleSubmit = jest.fn(); // <= this doesn't work!!
form.find('.submit-btn').simulate('click');
expect(form.find('.submit-btn').length).toEqual(1);
expect(handleSubmit).toHaveBeenCalled();
});
import React, { Component } from 'react';
import axios from 'axios';
class CarnetSidebarForm extends Component {
constructor(props) {
super(props);
this.state = {
title: ''
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(e) {
const target = e.target;
const value = target.value;
const name = target.name;
this.setState({
[name]: value
});
}
handleSubmit(e) {
e.preventDefault();
let payload = {
title: this.state.title
};
this.postCard(payload);
console.log('Payload: ', payload);
}
postCard(data) {
return axios.post('http://localhost:4000/api/cards', data)
.then(response => {
console.log('Response: ', response.message);
});
}
render() {
return (
<div className="card-form-panel">
<form className="card-form" onSubmit={this.handleSubmit}>
<div className="form-group">
<label htmlFor="card-title-field">Title</label>
<input className="form-control"
type="text"
placeholder="Title..."
id="card-title-field"
name="title"
value={this.state.title}
onChange={this.handleChange} />
</div>
<input className="card-submit-btn btn btn-primary" type="submit" value="Save" />
</form>
</div>
);
}
}
export default CarnetSidebarForm;
我一直收到此错误消息,现在很烦人:
expect(jest.fn()).toHaveBeenCalled()
Expected mock function to have been called.
但是,如果我在测试中创建了一个假组件,那么它就可以了
it('should submit form data', () => {
let handleSubmit = jest.fn();
// create a fake component
let form = mount(
<form onSubmit={handleSubmit}>
<input className="submit-btn" type="submit" value="Save" />
</form>
);
form.find('.submit-btn').simulate('submit');
expect(form.find('.submit-btn').length).toEqual(1);
expect(handleSubmit).toHaveBeenCalled();
});
是否与shallow()
或使用进口组件的enzyme
mount
? 我花了很多天寻找答案,但我迷路了。
添加到@rauliyohmc答案。 问题是,即使在模拟组件方法之后,它也不会被调用,而是调用实际方法。 所以,花了一些时间,我发现了一个解决方案。 在forceUpdate
其方法后,您需要forceUpdate
组件。
it('should submit form data', () => {
let form = mount(<Form />); // need to use mount to make it work.
form.instance().handleSubmit = jest.fn();
form.update(); // equivalent to calling form.instance().forceUpdate();
form.find('.submit-btn').simulate('submit'); // simulated event must be submit
expect(form.find('.submit-btn').length).toEqual(1);
expect(form.instance().handleSubmit).toHaveBeenCalled();
});
最小的例子: 要点
问题是你没有嘲笑组件方法本身,而是创建一个新的模拟函数并将其分配给一个随机变量。
尝试在呈现之前通过对象原型模拟方法,如下所示:
jest.mock('../Form'); // mock the component before importing it using the right path
import Form from '../Form';
...
it('should submit form data', () => {
Form.prototype.handleSubmit = jest.fn();
let form = shallow(<Form />);
form.find('.submit-btn').simulate('submit');
expect(form.find('.submit-btn').length).toEqual(1);
expect(Form.prototype.handleSubmit).toHaveBeenCalled();
});
注意 :不确定您使用的是哪个jest版本,但自Jest v15以来,默认情况下禁用自动插锁,因此您需要在将模块导入文件之前显式模拟该模块。
<input className="card-submit-btn btn btn-primary" type="submit" value="Save" />
你的组件没有使用className .submit-btn
,它使用的是.card-submit-btn
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.