监视从componentDidMount调用的组件方法时,永远不会调用该间谍 [英] When spying on component method, called from componentDidMount, the spy is never called

查看:334
本文介绍了监视从componentDidMount调用的组件方法时,永远不会调用该间谍的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在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()放在componentDidMountcustsomFunc中-它们会被调用. 我在做什么错了?

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()放在componentDidMountcustsomFunc中-他们会被呼叫.

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,但是到那时,已经太晚了,因为componentDidMountcustomFunc已经作为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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆