Jest 快照不适用于某些 Semantic-UI-React 组件
Jest snapshots not working with some Semantic-UI-React components
当我尝试创建包含 Semantic-UI-React 'Modal' 组件的 React 组件 'LoadingModal' 的 Jest 快照时,快照最终为空,.snap 文件中有 'null' .我已经测试了拍摄其他语义-UI-React 组件的快照,例如 'Button'、'Dropdown' 和 'Sidebar',它们使用正确的 html 进行渲染和快照输出就好了。
这看起来不像是 Jest 快照本身的问题,而是 react-test-renderer 它的 .create() 和 .toJson() 方法返回 null。
为什么 react-test-renderer 会正确地渲染一些语义-UI-React 组件,而不是像 'Modal' 这样的其他组件? react-test-render 似乎是序列化 React 组件以进行快照的标准方法,并且是 Jest's snapshotting docs.
中使用的方法
我正在使用 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 存储库中我的 issue。
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()
})
LoadingModal.test.js.snap
// Jest Snapshot v1
exports[`should render correctly 1`] = `null`;
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
如您所述,这可能是因为您在浏览器外部进行测试。但是,这可以使用 jsdom.
修复
我假设你有 jsdom 设置,因为 react-test-renderer
需要 jsdom 或其他一些模拟 window
和 document
的设置。
根据我的假设,Semantic-UI-React 的模态仍会呈现 null
。这是因为它使用了 Portal
component and renders the modal on the document.body
node.
Semantic-UI-React的解决方案
看看如何 Semantic-UI-React tests the modal:
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.')
})
他们必须使用 DOM 和 css 选择器来测试,因为 react-test-renderer
和 enzyme
无法针对 document.body
.[=30 进行测试=]
我的解决方案
我找到了另一个允许使用 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();
});
});
快照如下所示:
exports[`<CaptureModal /> snapshot 1`] = `
<div
className="ui modal transition visible active"
style={
Object {
"marginTop": undefined,
}
}
>
Inside my modal!
</div>
`;
当我尝试创建包含 Semantic-UI-React 'Modal' 组件的 React 组件 'LoadingModal' 的 Jest 快照时,快照最终为空,.snap 文件中有 'null' .我已经测试了拍摄其他语义-UI-React 组件的快照,例如 'Button'、'Dropdown' 和 'Sidebar',它们使用正确的 html 进行渲染和快照输出就好了。
这看起来不像是 Jest 快照本身的问题,而是 react-test-renderer 它的 .create() 和 .toJson() 方法返回 null。
为什么 react-test-renderer 会正确地渲染一些语义-UI-React 组件,而不是像 'Modal' 这样的其他组件? react-test-render 似乎是序列化 React 组件以进行快照的标准方法,并且是 Jest's snapshotting docs.
中使用的方法我正在使用 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 存储库中我的 issue。
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()
})
LoadingModal.test.js.snap
// Jest Snapshot v1
exports[`should render correctly 1`] = `null`;
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
如您所述,这可能是因为您在浏览器外部进行测试。但是,这可以使用 jsdom.
修复我假设你有 jsdom 设置,因为 react-test-renderer
需要 jsdom 或其他一些模拟 window
和 document
的设置。
根据我的假设,Semantic-UI-React 的模态仍会呈现 null
。这是因为它使用了 Portal
component and renders the modal on the document.body
node.
Semantic-UI-React的解决方案
看看如何 Semantic-UI-React tests the modal:
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.')
})
他们必须使用 DOM 和 css 选择器来测试,因为 react-test-renderer
和 enzyme
无法针对 document.body
.[=30 进行测试=]
我的解决方案
我找到了另一个允许使用 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();
});
});
快照如下所示:
exports[`<CaptureModal /> snapshot 1`] = `
<div
className="ui modal transition visible active"
style={
Object {
"marginTop": undefined,
}
}
>
Inside my modal!
</div>
`;