Jest快照不能与某些Semantic-UI-React组件一起使用

Rom*_*her 5 reactjs semantic-ui jestjs semantic-ui-react

当我尝试创建包含Semantic-UI- React'Modal'组件的React组件"LoadingModal"的Jest快照时,快照最终为空,在.snap文件中为'null'.我已经测试了其他Semantic-UI-React组件的快照,例如'Button','Dropdown'和'Sidebar',它们使用正确的html输出渲染和快照就好了.

这看起来不像Jest快照本身的问题,而是反应测试渲染器与其返回null的.create()和.toJson()方法.

为什么react-test-renderer会正确渲染一些Semantic-UI-React组件,而不是其他像'Modal'?react-test-render似乎是为快照序列化React组件的标准方法,也是Jest快照文档中使用的方法.

我使用的是react@16.2.0,jest @ 22.1.4,react-test-renderer @ 16.2.0和semantic-ui-react@0.77.1


更新:

看起来由于某种原因,Semantic-UI-React Modal组件特别设置为在浏览器中不呈现时呈现null.

有关更多信息,请参阅github repo上的问题.


LoadingModal.test.js

import React from 'react'
import renderer from 'react-test-renderer'
import LoadingModal from './LoadingModal'

test('should render correctly', () => {
    const tree = renderer.create(
        <LoadingModal/>
    ).toJSON()
    expect(tree).toMatchSnapshot()
})
Run Code Online (Sandbox Code Playgroud)

LoadingModal.test.js.snap

// Jest Snapshot v1

exports[`should render correctly 1`] = `null`;
Run Code Online (Sandbox Code Playgroud)

LoadingModal.js

import React from 'react';
import PropTypes from 'prop-types'

import { Modal, Dimmer, Loader} from 'semantic-ui-react'

class LoadingModal extends React.Component {
    static propTypes = {
        header: PropTypes.func,
        content: PropTypes.func,
        loading: PropTypes.bool,
        onClose: PropTypes.func,
        size: PropTypes.string,
        height: PropTypes.string
    };
    static defaultProps = {
        size: 'tiny',
        height: '500px'
    }

    _render_content = (content) => {
        if (this.props.loading === true) {
            return <Dimmer active inverted><Loader active size='large' inline='centered'/></Dimmer>
        } else {
            return content && content()
        }
    }

    render () {
        const {
          header,
          content,
          loading,
          onClose,
          size,
          height
        } = this.props;

        return (
            <Modal size={size} dimmer='blurring' open={true} onClose={onClose}>
              {header && header()}
              <Modal.Content>
                <div style={{height: height}}>
                    {this._render_content(content)}
                </div>
              </Modal.Content>
            </Modal>
        );
    }
}

export default LoadingModal
Run Code Online (Sandbox Code Playgroud)

And*_*erk 9

如您所述,这可能是因为您正在浏览器之外进行测试.但是,这可以使用jsdom来修复.

我将假设你有jsdom设置,因为react-test-renderer需要jsdom或其他一些模拟window和设置document.

根据我的假设,Semantic-UI-React的模态仍将呈现null.这是因为它使用了Portal组件并在document.body节点上呈现模态.

Semantic-UI-React的解决方案

看看Semantic-UI-React如何测试模态:

it('renders child components', () => {
  const child = <div data-child />
  wrapperMount(<Modal open>{child}</Modal>)

  document
    .querySelector('.ui.modal')
    .querySelector('[data-child]')
    .should.not.equal(null, 'Modal did not render the child component.')
})
Run Code Online (Sandbox Code Playgroud)

他们必须使用DOM和css选择器进行测试,因为react-test-renderer并且enzyme无法测试document.body.

我的解决方案

我找到了另一个允许使用react-test-renderer和的解决方案enzyme,这意味着你可以做快照!我jest.mock用来模拟Portal组件作为渲染其子document.body节点的组件,而不是渲染到节点上.

import React from 'react';
import renderer from 'react-test-renderer';
import Portal from 'semantic-ui-react/dist/commonjs/addons/Portal/Portal';
import { Modal } from 'semantic-ui-react';

jest.mock('semantic-ui-react/dist/commonjs/addons/Portal/Portal', () => ({ children }) => children);

describe('<Modal />', () => {
  test('snapshot', () => {
    const tree == renderer.create(<Modal open>Inside my modal!</Modal>).toJSON();

    expect(tree).toMatchSnapshot();
  });
});
Run Code Online (Sandbox Code Playgroud)

快照如下所示:

exports[`<CaptureModal /> snapshot 1`] = `
<div
  className="ui modal transition visible active"
  style={
    Object {
      "marginTop": undefined,
    }
  }
>
  Inside my modal!
</div>
`;
Run Code Online (Sandbox Code Playgroud)