Reputation: 1941
I'm writing some React/Flux code and using Jest to test it. So far it's been great, except my test are already taking a long time to complete.
The culprit seems to be resetting the mocks in between each test.
My general set up will look something like this:
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);
});
});
In my example if I don't reload the store in between the two tests I will get the wrong result for the number of calls to getDoobles
, which makes sense since it would be the same object.
But reloading the mock takes a bit of time and if I do lots of tests then they end up being slow.
I would love to just clone the object or call a reset function. There is a reset function for an individual function (mockClear()
) but there doesn't seem to be a global reset for the whole object. And I can't clone the object because the clone isn't the same object as the one that my React component is accessing, so none of the calls will get registered.
Which brings up the other issue. It seems I need to reload everything in the dependency chain. If I were to just re-require WidgetStore
then the object I have access to doesn't seem to be the same object that Widget
has access to.
If I just reload WidgetStore
and Widget
then I will often get errors which seem to be caused by having two copies of React loaded. So I end up having to reload React each time as well.
So is there a better way of doing this?
Upvotes: 4
Views: 5769
Reputation: 391
We set React and TestUtils variables before describe() and don't use jest.dontMock('react'). Also requires for Widget and WidgetStore could be there. In your case like this:
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);
});
});
Upvotes: 5