gpt4 book ai didi

javascript - 即使调用了 React 组件方法,expect(...).toHaveBeenCalled() 也会失败

转载 作者:行者123 更新时间:2023-11-29 17:37:44 25 4
gpt4 key购买 nike

我正在尝试测试是否使用 enzyme 和 jest 调用了 React 组件方法。该函数应该在 <section> 时被调用。元素变得没有焦点(模糊)。该组件连接到 Redux 存储,但它也按名称导出,以将 Redux 排除在外。下面是该组件的简化版本:

export class Section extends React.Component {
constructor(props) {
super(props)
this.formRef = React.createRef();
this.submitForm = this.submitForm.bind(this);
this.state = {
formSubmitted: false
}
}

submitForm() {
console.log("form submitted");
this.setState({ formSubmitted: true })
if (this.formRef && this.formRef.current) {
this.formRef.current.submit();
}
}

render() {
return (
<section onBlur={this.submitForm}>
<form ref={this.formRef} action={url} method='post'>
<input type="text" name="something" />
</form>
</section>
);
}
}

export default connect(
mapStateToProps,
mapDispatchToProps
)(Section);

我为 spyOn 尝试了各种组合部分,因为它似乎是问题的根源。都失败了。

import React from 'react';
import { shallow } from 'enzyme';
import { Section } from './Section';

describe('Section', () => {
it('should submit form on blur', () => {
const wrapper = shallow(<Section content={{ body: [] }} />);
const spy = spyOn(wrapper.instance(), 'submitForm');
const spy2 = spyOn(Section.prototype, 'submitForm');
const spy3 = jest.spyOn(wrapper.instance(), 'submitForm');
const spy4 = jest.spyOn(Section.prototype, 'submitForm');

wrapper.find('section').simulate('blur');
expect(wrapper.state().formSubmitted).toEqual(true);
expect(spy).toHaveBeenCalled();
expect(spy2).toHaveBeenCalled();
expect(spy3).toHaveBeenCalled();
expect(spy4).toHaveBeenCalled();
})
})

除了测试expect(...).toHaveBeenCalled,我还给了组件一个状态并测试了它为了验证函数是否真的被调用了,看起来确实如此。

console.log('form submitted')出现在控制台中。

测试expect(wrapper.state().formSubmitted).toEqual(true);通过,这向我表明正在调用正确的函数。但是,我不想为了测试而出现不必要的状态。刚刚添加了状态以断言正在调用“submitForm”方法。

断言 expect(...).toHaveBeenCalled()全部失败并显示错误 Expected spy to have been called, but it was not calledExpected mock function to have been called, but it was not called.

最佳答案

有趣的是,这个问题直接深入到 JavaScript 的一些更不寻常的方面。


发生了什么

submitForm 最初定义为 prototype method :

class Section extends React.Component {
...
submitForm() { ... }
...
}

...这意味着您将像这样创建 spy:

jest.spyOn(Section.prototype, 'submitForm');

...但随后它被重新定义为 instance property构造函数中:

this.submitForm = this.submitForm.bind(this);

...意味着您将现在像这样创建 spy :

jest.spyOn(wrapper.instance(), 'submitForm');

...但是 仍然 不起作用,因为 onBlur直接 绑定(bind)到 this.submitForm渲染期间:

<section onBlur={this.submitForm}>

因此,当前编写代码的方式实际上使得无法监视 submitForm,因为创建 spy 需要一个 instanceinstance 在组件呈现之前不可用,并且 onBlur 在呈现期间直接绑定(bind)到 this.submitForm


解决方案

onBlur 更改为 调用 this.submitForm 的函数,以便每当 onBlur 触发时它都会调用this.submitForm当前值:

render() {
return (
<section onBlur={() => this.submitForm()}>
<form ref={this.formRef} action={url} method='post'>
<input type="text" name="something" />
</form>
</section>
);
}

...然后当您将 submitForm 替换为 instance 上的 spy 时,spy 将被调用当 onBlur 触发时:

describe('Section', () => {
it('should submit form on blur', () => {
const wrapper = shallow(<Section content={{ body: [] }} />);
const spy = jest.spyOn(wrapper.instance(), 'submitForm');

wrapper.find('section').simulate('blur');
expect(wrapper.state().formSubmitted).toEqual(true);
expect(spy).toHaveBeenCalled(); // Success!
})
})

关于javascript - 即使调用了 React 组件方法,expect(...).toHaveBeenCalled() 也会失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55227855/

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