监视 componentDidMount 中的方法调用

Posted

技术标签:

【中文标题】监视 componentDidMount 中的方法调用【英文标题】:spy on method call in componentDidMount 【发布时间】:2019-01-29 16:56:32 【问题描述】:

我想测试一些在 React 组件的 componentDidMount 生命周期方法中调用的自定义方法。

  componentDidMount() 
    getData().then(res => 
      console.log(res);
      this.setState(
        rate: res.data.bpi.USD.rate_float
      );
    );
  

我正在从 api.js 导入 getData 方法:

export const getData = () => 
  return axios
    .get("https://api.coindesk.com/v1/bpi/currentprice.json")
    .then(res => 
      return res;
    );
;

像这样用 Jest 和 Enyzme 测试它:

describe("App", () => 
  describe("Calls getData when componentDidMount", () => 
    const spy = jest.spyOn(App.prototype, "getData");
    const wrapper = mount(<App ...props />);
    wrapper.instance().getData();
    expect(spy).toHaveBeenCalled(1);
  );
);

失败:App › Calls getData when componentDidMount › encountered a declaration exception

并给我以下错误:

TypeError: Cannot read property '_isMockFunction' of undefined

我做错了什么?

【问题讨论】:

什么是getData,它在哪里定义? getData() - 这不是 App 方法。 @estus 我正在从另一个文件中导入它。如果我从另一个文件中导入它,我该如何测试它? 你能在问题中显示这个吗?与代码相关的问题应包含 ***.com/help/mcve 。然后你不能在 App.prototype 上窥探它。因为它不是一种方法。这很可能应该通过jest.mock 完成。 @estus 更新了问题。 尝试将const spy 放在const wrapper 下方。而不是App.prototype 尝试wrapper.instance() 【参考方案1】:

getData 不是App 方法,它不能在App 类上被窥探,它在wrapper.instance() 组件实例上不可用。

可以使用jest.mock 模拟模块。正确的单元测试需要模拟除测试单元之外的所有内容。 axios 请求可以被模拟为:

import  getData  from '.../api';

jest.mock('.../api');

describe("App", () => 
  describe("Calls getData when componentDidMount", () => 
    getData.mockResolvedValue( data: ... );
    const wrapper = mount(<App ...props />);
    expect(getData).toHaveBeenCalled(1);
  );
);

注意shallow enables lifecycle hooks by default,预计componentDidMount 在组件实例化时被调用。

getData 可以通过模拟axios 以类似的方式进行测试; this is shown in the manual.

【讨论】:

以上是关于监视 componentDidMount 中的方法调用的主要内容,如果未能解决你的问题,请参考以下文章

间谍在componentDidMount中的方法调用

渲染在另一个组件的渲染函数中声明的组件不包括对 REACT 17 中 componentDidMount 方法的更改

使用 Redux 无法在 componentDidMount 中接收异步响应

react native中componentdidmount和componentdidupdate之间的区别是什么

如何动态调用componentDidMount中的函数?

`render` 和 `componentDidMount` 之间 Store 中的竞争条件