当我尝试创建包含Semantic-UI-React 'Modal'组件的React组件“LoadingModal”的Jest快照时,快照最终为空,在.snap文件中为“null”。我已经测试了其他Semantic-UI-React组件的快照,比如'Button','Dropdown'和'Sidebar',它们使用正确的html输出渲染和快照就好了。
这看起来不像Jest快照本身的问题,而是react-test-renderer,其.create()和.toJson()方法返回null。
为什么react-test-renderer会正确渲染一些Semantic-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 repo上的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
答案 0 :(得分:9)
正如您所说,这可能是因为您在浏览器之外进行测试。但是,可以使用jsdom修复此问题。
我将假设你有jsdom设置,因为react-test-renderer
需要jsdom或其他一些模拟window
和document
的设置。
根据我的假设,Semantic-UI-React的模态仍将呈现null
。这是因为它使用Portal
组件并在document.body
node上呈现模态。
看看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
进行测试。
我找到了另一个允许使用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>
`;