监视从componentDidMount调用的组件方法时,永远不会调用该间谍

时间:2019-01-24 15:07:53

标签: reactjs jestjs enzyme

我在React组件中有

git config --global core.autocrlf true

当我尝试使用Jest和酶测试这种方法时:

export default class MyComp extends Component {
  ...
  componentDidMount() {
    this.customFunc();
  }
  customFunc = () => {
    // ..
  }
  ...
}

它失败并显示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中,它们会被呼叫。 我在做什么错了?

PS:我在实例上尝试使用custsomFunc,就在期望值之前,但是我仍然遇到相同的错误。

1 个答案:

答案 0 :(得分:2)

  

它失败并显示Expected mock function to have been called, but it was not called.

     

有趣的是,如果我将console.log()放在componentDidMountcustsomFunc中,它们会被呼叫。

调用mount会呈现该组件,并且componentDidMount在该过程中会被调用,而该过程又会调用customFunc

然后在spy上创建customFunc,但是到那时为止已经太晚了,因为componentDidMountcustomFunc已经作为mount的一部分运行了,并且测试失败,spy报告未调用。


  

我在做什么错了?

在调用它们之前,需要在spy 上创建customFunc

由于customFunc被实现为 instance属性,因此当前编写代码的方式非常困难。

由于它是一个实例属性,因此在该实例存在之前将不存在,但是在渲染过程中创建了该实例,最终调用了componentDidMount

换句话说,您需要一个实例来监视customFunc,但是在创建该实例的过程中会调用customFunc

在这种情况下,检查customFunc运行时是否调用componentDidMount的唯一方法是在创建实例并渲染组件之后再次调用 ,这是一种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作为类方法实现。

如果customFunc是一个类方法,则它将存在于该类的prototype上,允许您在实例之前的customFunc 上创建间谍在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
});