我正在尝试为使用Jest的组件编写React.Suspense单元测试。
正在测试的组件模块的简化版本:
MyComponent.js
import React from 'react';
export default () => <h1>Tadaa!!!</h1>;
MySuspendedComponent.js
import React, { Suspense } from 'react';
import MyComponent from './MyComponent';
export default () => (
<Suspense fallback={<div>Loading…</div>}>
<MyComponent />
</Suspense>
);
天真的,在我的第一次尝试中,我编写了一个使用Enzyme来挂起挂起的组件的单元测试:
MySuspendedComponent.test.js
import React from 'react';
import { mount } from 'enzyme';
import MySuspendedComponent from './MySuspendedComponent';
test('the suspended component renders correctly', () => {
const wrapper = mount(<MySuspendedComponent />);
expect(wrapper.html()).toMatchSnapshot();
});
这会导致测试崩溃并显示错误消息:
错误:酶内部错误:标记为13的未知节点
在网络上搜索错误消息时,我发现这很可能是由于酶尚未准备好渲染Suspense
(至今)引起的。
如果我使用shallow
而不是mount
,错误消息将变为:
永久违反:ReactDOMServer尚不支持Suspense
我的下一个尝试是使用虚拟的传递组件来模拟Suspense
,如下所示:
MySuspendedComponent.test.js
import React from 'react';
import { mount } from 'enzyme';
import MySuspendedComponent from './MySuspendedComponent';
jest.mock('react', () => {
const react = require.requireActual('react');
return () => ({
...react,
Suspense({ children }) {
return children;
}
});
});
test('the suspended component renders correctly', () => {
const wrapper = mount(<MySuspendedComponent />);
expect(wrapper.html()).toMatchSnapshot();
});
想法是对React模块进行模拟实现,其中包含React库中的所有实际代码,只有Suspense
被模拟函数代替。
如Jest documentation所述,我已将此模式与requireActual
一起使用,在模拟除React以外的其他模块时,已在其他单元测试中成功使用,但是在React中,它不起作用。
我现在得到的错误是:
TypeError:((($ _ $ w(...), react)||($ $ w(...),_load_react(...)))。default.createElement不是功能
...我认为这是由于我的模拟技巧之后无法使用React的原始实现引起的。
如何在保持其余React库其余部分不变的情况下模拟Suspense?
还是有另一种更好的方法来测试悬挂的组件?
答案 0 :(得分:1)
解决方案不是使用对象扩展来导出原始的React模块,而是简单地覆盖Suspense
属性,如下所示:
MySuspendedComponent.test.js
import React from 'react';
import { mount } from 'enzyme';
import MySuspendedComponent from './MySuspendedComponent';
jest.mock('react', () => {
const React = jest.requireActual('react');
React.Suspense = ({ children }) => children;
return React;
});
test('the suspended component renders correctly', () => {
const wrapper = mount(<MySuspendedComponent />);
expect(wrapper.html()).toMatchSnapshot();
});
这将按预期创建以下快照:
MySuspendedComponent.test.js.snap
exports[`the suspended component renders correctly 1`] = `"<h1>Tadaa!!!</h1>"`;