使用Jest监视componentDidMount中的方法调用

sea*_*n11 37 javascript testing reactjs jestjs enzyme

我最近想测试一些自定义方法在componentDidMountReact组件的方法中有条件地调用.

componentDidMount() {
  if (this.props.initOpen) {
    this.methodName();
  }
}
Run Code Online (Sandbox Code Playgroud)

我正在使用Jest作为我的测试框架,其中包括jest.fn()模拟/间谍.我已经读过,通过做类似以下的事情,用Sinon测试这将是相当微不足道的:

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

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

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

此代码失败并引发以下错误:

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

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

Jon*_*han 60

关键是使用jests spyOn方法.它应该是这样的:

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

正如在此发现的那样:测试函数是否被称为反应和酶

请注意,最佳做法是在每次测试运行后清除间谍功能

let spy

afterEach(() => {
  spy.mockClear()
})
Run Code Online (Sandbox Code Playgroud)

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

  • 如果 `&lt;Component {...props} /&gt;` 用 `&lt;Provider&gt;` 包裹起来,这会起作用吗?我收到“无法读取未定义的属性‘_isMockFunction’”。但不确定是否是因为上述原因。 (2认同)

hlo*_*rey 16

我知道它有点晚了,但我遇到了这个,并建议测试componentDidMount启动你的嵌套方法的调用,你的测试应该是这样的:

模

componentDidMount() {
  if (this.props.initOpen) {
    this.methodName();
  }
}
Run Code Online (Sandbox Code Playgroud)

测试 - 很好

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

如果你调用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();
}
Run Code Online (Sandbox Code Playgroud)

通过这样编写测试 - 您调用该方法然后断言它被调用.当然它会让你刚刚调用它.