我正在写一些React / Flux代码并使用Jest来测试它。到目前为止,它很棒,除了我的测试已经花了很长时间才完成。
罪魁祸首似乎是在每次测试之间重置模拟。
我的一般设置看起来像这样:
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
的结果,这是有意义的,因为它将是同一个对象。
但是重新加载模拟会花费一些时间,如果我做了很多测试,那么它们最终会变慢。
我很乐意克隆对象或调用重置函数。单个函数(mockClear()
)有一个重置函数,但似乎并不是整个对象的全局重置。而且我无法克隆该对象,因为克隆与我的React组件访问的对象不同,因此所有调用都不会被注册。
这引出了另一个问题。看来我需要重新加载依赖链中的所有内容。如果我只是重新要求WidgetStore
,那么我有权访问的对象似乎与Widget
无法访问的对象相同。
如果我只是重新加载WidgetStore
和Widget
,那么我经常会收到似乎由having two copies of React loaded引起的错误。所以我最终每次都要重新加载React。
那么有更好的方法吗?
答案 0 :(得分:5)
我们在describe()之前设置了React和TestUtils变量,并且不使用jest.dontMock('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);
});
});