我如何使用 Jest 来监视方法调用?

How can I use Jest to spy on a method call?

我最近想测试一些自定义方法是否在 React 组件的 componentDidMount 方法中被有条件地调用。

componentDidMount() {
  if (this.props.initOpen) {
    this.methodName();
  }
}

我使用 Jest 作为我的测试框架,其中包括 jest.fn() for mocks/spies。我已经读到,通过执行以下操作,用 Sinon 进行测试是相当微不足道的:

sinon.spy(Component.prototype, "methodName");
const wrapper = mount(<Component {...props} />);
expect(wrapper.instance().methodName).toHaveBeenCalled();

我正在尝试用 Jest 重新创建这个:

Component.prototype.methodName = jest.fn();
const wrapper = mount(<Component {...props} />);
expect(wrapper.instance().methodName).toHaveBeenCalled();

此代码失败并抛出以下错误:

jest.fn() value must be a mock function or spy.
Received:
  function: [Function bound mockConstructor]

是否可以使用 Jest 测试此功能?如果是,怎么做?

关键是在对象的 prototype 上使用 jests spyOn 方法。应该是这样的:

const spy = jest.spyOn(Component.prototype, 'methodName');
const wrapper = mount(<Component {...props} />);
wrapper.instance().methodName();
expect(spy).toHaveBeenCalled();

在此处找到例如:

请注意 最好在每次测试后清除间谍功能运行

let spy

afterEach(() => {
  spy.mockClear()
})

https://facebook.github.io/jest/docs/en/jest-object.html#jestclearallmocks

我知道有点晚了,但我遇到了这个并建议测试 componentDidMount 启动对您的嵌套方法的调用,您的测试应该类似于:

模块

componentDidMount() {
  if (this.props.initOpen) {
    this.methodName();
  }
}

测试 - 好

it('should call methodName during componentDidMount', () => {
    const methodNameFake = jest.spyOn(MyComponent.prototype, 'methodName');
    const wrapper = mount(<MyComponent {...props} />);
    expect(methodNameFake).toHaveBeenCalledTimes(1);
});

如果您调用 componentDidMount,那么 methodName 是通过 componentDidMount 调用的断言更有效。

测试 - 差

it('should call methodName during componentDidMount', () => {
    const spy = jest.spyOn(Component.prototype, 'methodName');
    const wrapper = mount(<Component {...props} />);
    wrapper.instance().methodName();
    expect(spy).toHaveBeenCalled();
}

通过像这样编写测试 - 您调用该方法,然后断言它已被调用。当然它会给你调用它。

如果您尝试测试在 componentDidMount 上调用的 public 方法(如果您使用的是 TypeScript),则需要显式调用 instancecomponentDidMount 方法调用,因为 public 方法在组件实例化后才定义。

要测试这样的东西:

代码

public componentDidMount() {
  if (this.props.initOpen) {
    this.methodName();
  }
}

public methodName = () => {
  // some code here
}

测试

it('should call methodName during componentDidMount', () => {
  const wrapper = mount(<MyComponent {...props} />);
  const instance = wrapper.instance();
  jest.spyOn(instance, 'methodName')
  expect(instance.methodName).toHaveBeenCalled();
});
const toastMethodSpy = jest.spyOn(sharedMockedOTPComponent, 'toast')
sharedMockedOTPComponent.handleResendOtpFailure(networkError)

//hide loader
expect(sharedMockedOTPComponent.state.showLoader).toBe(false)
//error message in toast should have been shown
expect(toastMethodSpy).toHaveBeenCalledTimes(1)