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

时间:2017-01-04 10:01:38

标签: reactjs sinon jestjs enzyme

完整DOM渲染的酶文档here包含以下使用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相同的函数间谍。

关于模拟函数实际工作方式的Jest文档有点受限。我已经围绕jest.fn()正在进行的讨论here进行了讨论,但似乎它并不是真正等同于sinon.spy()。

如何使用Jest复制该测试?

2 个答案:

答案 0 :(得分:3)

这不适用于jest,因为jest.fn只有实现参数。但更重要的是,你不应该窥探你要测试的对象的内部。您应该将Foo视为一个黑盒子,您可以在其中放入一些属性并获取一些东西。然后你意识到没有必要测试Foo的内部函数,如componentDidMount,被调用。唯一重要的是黑匣子的输出。

但如果你真的想要测试它呢:

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

答案 1 :(得分:1)

从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会返回mock function,其中包含mockClearmockResetmockRestore等所有常用方法。

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