监视从componentDidMount调用的组件方法时,永远不会调用该间谍 [英] When spying on component method, called from componentDidMount, the spy is never called
问题描述
我在React组件中有
In a React component I have
export default class MyComp extends Component {
...
componentDidMount() {
this.customFunc();
}
customFunc = () => {
// ..
}
...
}
当我尝试用Jest和酶测试这种方法时:
And when I try to test this method with Jest and Enzyme like this:
it('Should call customFunc on mount', () => {
const MyCompInstance = mount(<MyComp {...props} >).instance();
const spy = jest.spyOn(MyCompInstance, 'customFunc');
expect(spy).toHaveBeenCalled();
});
它失败,并显示Expected mock function to have been called, but it was not called.
有趣的是,如果我将console.log()
放在componentDidMount
和custsomFunc
中-它们会被调用.
我在做什么错了?
The funny thing is that if I put console.log()
in componentDidMount
and in custsomFunc
- they get called.
What am I doing wrong?
PS:我在实例上尝试了forceUpdate
,就在期望值之前,但是我仍然遇到相同的错误.
PS: I tried with forceUpdate
on the instance, right before the expect, but I still get the same error.
推荐答案
它失败,并显示
Expected mock function to have been called, but it was not called.
有趣的是,如果我将console.log()
放在componentDidMount
和custsomFunc
中-他们会被呼叫.
The funny thing is that if I put console.log()
in componentDidMount
and in custsomFunc
- they get called.
调用mount
会渲染该组件,而componentDidMount
会在该过程中被调用,而该过程又会调用customFunc
.
Calling mount
renders the component and componentDidMount
gets called as part of that process, which in turn calls customFunc
.
然后在customFunc
上创建spy
,但是到那时,已经太晚了,因为componentDidMount
和customFunc
已经作为mount
的一部分运行,并且测试失败,spy
报告它没有被召唤.
The spy
then gets created on customFunc
but by that time it is too late since componentDidMount
and customFunc
have already run as part of mount
and the test fails with the spy
reporting that it was not called.
我在做什么错了?
What am I doing wrong?
在调用customFunc
之前,您需要在customFunc
上创建spy
.
You need to create the spy
on customFunc
before it gets called.
由于customFunc
被实现为 instance属性,因此当前编写代码的方式非常困难.
This is very difficult the way the code is currently written since customFunc
is implemented as an instance property.
由于它是一个实例属性,因此在该实例存在之前将不存在,但是在渲染过程中创建了该实例,最终调用了componentDidMount
.
Because it is an instance property it won't exist until the instance exists but the instance gets created during the rendering process which ends up calling componentDidMount
.
换句话说,您需要一个实例来监视customFunc
,但是在创建该实例时会调用customFunc
.
In other words, you need an instance to spy on customFunc
, but customFunc
gets called as part of creating the instance.
在这种情况下,检查componentDidMount
运行时是否调用customFunc
的唯一方法是在实例创建并渲染组件之后再次调用 .骇客:
In this scenario the only way to check if customFunc
is called when componentDidMount
runs is to call it again after the instance has been created and the component has rendered, which is kind of a hack:
import * as React from 'react';
import { mount } from 'enzyme';
class MyComp extends React.Component {
componentDidMount() {
this.customFunc();
}
customFunc = () => { } // instance property
render() { return <div/> }
}
it('Should call customFunc on mount', () => {
const instance = mount(<MyComp />).instance();
const spy = jest.spyOn(instance, 'customFunc'); // spy on customFunc using the instance
instance.componentDidMount(); // call componentDidMount again...kind of a hack
expect(spy).toHaveBeenCalled(); // SUCCESS
});
替代方法是将customFunc
实现为 class方法.
The alternative is to implement customFunc
as a class method.
如果customFunc
是类方法,则它将存在于该类的prototype
上,这允许您在渲染过程中创建实例之前在customFunc
上创建间谍在mount
:
If customFunc
is a class method then it will exist on the prototype
of the class which allows you to create a spy on customFunc
before the instance gets created during the render process in mount
:
import * as React from 'react';
import { mount } from 'enzyme';
class MyComp extends React.Component {
componentDidMount() {
this.customFunc();
}
customFunc() { } // class method
render() { return <div/> }
}
it('Should call customFunc on mount', () => {
const spy = jest.spyOn(MyComp.prototype, 'customFunc'); // spy on customFunc using the prototype
const wrapper = mount(<MyComp />);
expect(spy).toHaveBeenCalled(); // SUCCESS
});
这篇关于监视从componentDidMount调用的组件方法时,永远不会调用该间谍的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!