在使用Jest进行测试时,是否有更快的方法重置mock

Is there a faster way to reset a mock when testing with Jest?

本文关键字:方法 mock 是否 Jest 测试      更新时间:2023-09-26

我正在编写一些React/Flux代码,并使用Jest对其进行测试。到目前为止,它非常棒,只是我的测试已经需要很长时间才能完成。

罪魁祸首似乎是在每次测试之间重置mock。

我的总体设置如下:

jest.dontMock('react');
jest.dontMock('../Widget.jsx');
describe('Widget', function() {
  var React, TestUtils, Widget, WidgetStore;
  beforeEach(function() {
    React = require('react/addons');
    TestUtils = React.addons.TestUtils;
    WidgetStore = require('../WidgetStore');
    Widget = require('../Widget');
  });
  it('should fetch initial state from the store', function() {
    WidgetStore.getDoobles.mockReturnValueOnce({});
    var widget = TestUtils.renderIntoDocutment(
      <Widget />
    );
    expect(WidgetStore.getDoobles.mock.calls.length).toBe(1);
  });
  it('should refresh its data when clicked', function() {
    WidgetStore.getDoobles.mockReturnValueOnce({});
    var widget = TestUtils.renderIntoDocutment(
      <Widget />
    );
    WidgetStore.getDoobles.mockReturnValueOnce({'foo': 'bar'});        
    TestUtils.Simulate.click(widget);
    expect(WidgetStore.getDoobles.mock.calls.length).toBe(2);
  });
});

在我的例子中,如果我不在两个测试之间重新加载存储,我将得到对getDoobles调用次数的错误结果,这是有道理的,因为它将是同一个对象。

但是重新加载mock需要一些时间,如果我做了很多测试,那么它们最终会很慢。

我希望只是克隆对象或调用重置函数。单个函数(mockClear())有一个重置函数,但似乎没有对整个对象进行全局重置。我无法克隆该对象,因为克隆的对象与我的React组件正在访问的对象不同,所以不会注册任何调用。

这就引出了另一个问题。我似乎需要重新加载依赖链中的所有内容。如果我只是重新需要WidgetStore,那么我可以访问的对象似乎与Widget可以访问的不同。

如果我只是重新加载WidgetStoreWidget,那么我经常会收到错误,这些错误似乎是由加载了两个React副本引起的。所以我每次都要重新加载React。

那么,有更好的方法吗?

我们在describe()之前设置了React和TestUtils变量,并且不使用jest.dontLock("React")。Widget和WidgetStore也需要。在你这样的情况下:

jest.dontMock('../Widget.jsx');
var React = require('react/addons');
var TestUtils = React.addons.TestUtils;
var WidgetStore = require('../WidgetStore');
var Widget = require('../Widget');
describe('Widget', function() {
  var widget;
  beforeEach(function() {
    widget = TestUtils.renderIntoDocument(
      <Widget />
    );
    WidgetStore.getDoobles.mockClear();
  });
  it('should fetch initial state from the store', function() {
    WidgetStore.getDoobles.mockReturnValueOnce({});
    expect(WidgetStore.getDoobles.mock.calls.length).toBe(1);
  });
  it('should refresh its data when clicked', function() {
    WidgetStore.getDoobles.mockReturnValueOnce({});
    WidgetStore.getDoobles.mockReturnValueOnce({'foo': 'bar'});        
    TestUtils.Simulate.click(widget);
    expect(WidgetStore.getDoobles.mock.calls.length).toBe(2);
  });
});