代码之家  ›  专栏  ›  技术社区  ›  Patrick Hund

模仿反应。在保持其余反应完整的同时暂停。

  •  0
  • Patrick Hund  · 技术社区  · 6 年前

    我想写一篇 Jest 使用的组件的单元测试 React.Suspense .

    正在测试的组件模块的简化版本:

    MyCalpTun.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尚不支持暂挂

    我的下一次尝试是模仿 悬念 使用一个虚拟的直通组件,如下所示:

    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模块进行模拟实现,仅 悬念 被模拟函数替换。

    我用这个图案 requireActual ,如中所述 Jest documentation 在模拟除react以外的其他模块时,在其他单元测试中成功,但使用react时,它不起作用。

    我现在得到的错误是:

    类型错误:(($$W(…), 反应)($) $w(…),_load_react(…)).default.createElement不是函数

    _我认为,这是因为在我的模拟技巧之后,react的原始实现不可用。

    我怎样才能在保持反应库其余部分完好无损的情况下模拟出悬念呢?

    或者还有其他更好的方法来测试悬浮组件吗?

    1 回复  |  直到 6 年前
        1
  •  1
  •   Patrick Hund    6 年前

    解决方案不是使用对象扩展来导出原始的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>"`;