【问题标题】:how to use jest to mock method of react class如何使用 jest 来模拟反应类的方法
【发布时间】:2019-08-02 09:42:41
【问题描述】:

我想模拟反应类的方法,以便单元测试可以跟随模拟功能运行。

反应:16.8.6 开玩笑:24.8.0

Overview.js

import React from 'react';
export default class Overview extends Component{
  test1(){
    return {
      // fetch api
    } 
  }

  test2(){
    const result = this.test1();
    // do other thing
    return result 
  }
}

overview.test.js

import Overview from './index';
import { mount } from 'enzyme';
import React from 'react';
describe('test Overview',()=>{
  const mockResult = {test1:'test1'};
  console.info(Overview.prototype)  // {}
  Overview.prototype.test1=jest.fn(()=>{
    return mockResult
  });
  it('func test2',()=>{
    const wrapper = mount(<Overview/>);
    const {test2} = wrapper.instance();
    expect(mockResult).toEqual(test2())
  })
})

期望:运行成功

实际结果:运行失败,因为 Overview.prototype 无法覆盖或模拟 test1 函数。

当我尝试打印“Overview.prototype”时,我得到了 {}。这让我很困惑。

如何模拟 test1 函数以及为什么不能覆盖概览?

请帮帮我。

【问题讨论】:

  • 我试图从官方api中找到一些东西。 api 使用 jest.fn(), jest.spyon() 来模拟函数,但这些演示只模拟整个函数或模块,而不是类的单个方法。

标签: reactjs unit-testing jestjs


【解决方案1】:

尝试这样做:

it('func test2',()=>{
    const wrapper = mount(<Overview/>);
    wrapper.instance().test1 = jest.fn(() => mockResult);
    expect(wrapper.instance().test2()).toEqual(mockResult);
  })

【讨论】:

  • 感谢您的回复。 wrapper.instance().test1 = jest.fn(() =&gt; mockResult);不能改变Overview.prototype,所以expect(wrapper.instance().test2()).toEqual(mockResult);不能工作。
【解决方案2】:

除了模拟内部方法和检查内部方法之外,还有很多理由选择不同的方法:

  1. 有时很难甚至不可能(一旦方法在模拟更改状态下,甚至通过闭包访问变量)
  2. 您坚持实现细节,因此即使是最小的重构(重命名 state 中的内部方法或属性名称)也会让您更新大量测试
  3. 它让您对自己的组件更加自信(假设test1() 停止调用fetch() 会怎样?但您的模拟测试甚至不会知道该组件已损坏)

这是不同的方法:仅模拟外部 API 并仅通过公共接口进行通信(对于 React 组件,它是 propsrender() 结果,您可以使用 Enzyme 的方法访问,例如 .find().filter().text() 等)

有几个包可以模拟全局fetch(),比如fetch-mock,但实际上你可以自己模拟它(别忘了用Promise 模拟它而不是普通数据):

global.fetch = jest.fn();

beforeEach(() => {
  // important for mocks to keep them fresh on each test case run
  global.fetch.mockClear(); 
});

it('renders error if fetching failed', async () => {
  global.fetch.mockReturnValue(Promise.reject({}));
  const wrapper = shallow(<Overview />);
  wrapper.find('.some-button-to-click').props().onClick();
  await Promise.resolve(); // let's wait till mocked fetch() is resolved
  expect(wrapper.find('.error').text()).toEqual('Unable to load users. Try later.');
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-08
    • 2020-03-31
    • 2020-06-21
    • 2019-02-02
    • 1970-01-01
    • 1970-01-01
    • 2017-09-30
    • 1970-01-01
    相关资源
    最近更新 更多