如何使用 Jest 和 Enzyme 模拟 React 组件生命周期方法?

IT技术 reactjs sinon jestjs enzyme
2021-05-18 05:03:49

此处的完整 DOM 渲染的酶文档包含以下使用 Sinon 监视生命周期方法的示例:

describe('<Foo />', () => {

  it('calls componentDidMount', () => {
    sinon.spy(Foo.prototype, 'componentDidMount');
    const wrapper = mount(<Foo />);
    expect(Foo.prototype.componentDidMount.calledOnce).to.equal(true);
  });
});

使用 Jest 的模拟函数与此等效的是什么?

我正在使用 Create-React-App,如果使用 Jest 可以实现同样的效果,我宁愿不包括 Sinon。

这是我希望测试的样子:

describe('<App />', () => {

  it('calls componentDidMount', () => {
    jest.fn(App.prototype, 'componentDidMount');
    const wrapper = mount(<App />);
    expect(App.prototype.componentDidMount.mock.calls.length).toBe(1);
  });
});

在这种情况下,App.prototype.componentDidMount不会像使用 Sinon 那样引用相同的函数 spy。

关于模拟函数实际工作方式的 Jest 文档有点有限。我随后的讨论在这里周围有什么jest.fn()是干什么的,但现在看来,这不是真的等同于sinon.spy()。

如何使用 Jest 复制该测试?

2个回答

这不会以这种方式与 jest 一起使用,因为jest.fn只有一个用于实现的参数。但更重要的是,您不应窥探要测试的对象的内部结构。您应该将其Foo视为一个黑匣子,您可以在其中放入一些属性并返回一些内容。然后您意识到没有必要测试 的内部函数Foo,例如componentDidMount,被调用。唯一重要的是黑匣子的输出。

但如果你真的想测试它:

const spy = jest.fn()
const componentDidMount = Foo.prototype.componentDidMount
Foo.prototype.componentDidMount = function(){
  spy()
  componentDidMount()
}

从 Jest 19 开始,你可以这样做:

describe('<App />', () => {
  it('calls componentDidMount', () => {
    const spy = jest.spyOn(App.prototype, 'componentDidMount');
    const wrapper = mount(<App />);
    expect(spy).toHaveBeenCalled();
    spy.mockReset();
    spy.mockRestore();
  });
});

jest.spyOn返回一个模拟函数,其中包含所有通常可用的方法,例如mockClear,mockResetmockRestore

确保在mount使用酶或createreact-test-renderer之前设置您的间谍,以便创建的实例具有对被监视的模拟函数的引用。