我有一个带有模式对话框的 React 组件(使用 reactstrap
构建,但其他人报告了 react-bootstrap
和其他类型的模式组件的类似问题)。 Enzyme 无法找到模态中的任何组件,即使它们在实际应用程序中呈现良好。最小示例:
import React from 'react'
import { Modal } from 'reactstrap'
export default class MyModal extends React.Component {
render() {
return (
<div className="outside"> Some elements outside of the dialog </div>
<Modal isOpen={this.props.modalOpen}>
<div className="inside"> Content of dialog </div>
</Modal>
);
}
}
我想像这样测试内容(在本例中使用 jest
)
import React from 'react'
import MyModal from './MyModal'
import { mount } from 'enzyme'
it('renders correctly', () => {
const wrapper = mount( <MyModal modalOpen/> );
expect(wrapper).toMatchSnapshot();
// Passes
expect(wrapper.find('.outside')).toHaveLength(1);
// Fails, 0 length
expect(wrapper.find('.inside')).toHaveLength(1);
});
测试正确找到了 Modal 之外的内容,但没有找到里面的任何内容。查看快照表明,<Modal>
内确实没有任何内容。被渲染。但是,如果我替换 mount
它确实有效与 shallow
。问题是我需要 mount
测试生命周期方法,如 componentDidMount
.
为什么不mount
渲染模式的内容?我认为重点在于它渲染了整个子元素树。
最佳答案
编辑:这在 React 16 + Enzyme 3 中不再是问题,因为 React 16 supports portal components .
在 React 15 及之前版本中,问题在于模式对话框(在大多数实现中)是 portal成分。这意味着它创建直接附加到文档根的 DOM 元素,而不是父 React 组件的子元素。
ReactWrapper
的 find
方法create by mount
从顶级组件创建的元素开始查找 DOM,因此它找不到模态框的内容。但 Enzyme 的 shallow
并不附加到 DOM,而是构建自己的包含模式内容的组件树。
要测试门户组件,您首先需要找到已附加到文档正文的 DOM 元素。然后您可以围绕它们创建一个新的 ReactWrapper
,以便所有常用的 Enzyme 功能都可以工作:
import React from 'react'
import MyModal from './MyModal'
import { mount, ReactWrapper } from 'enzyme'
it('renders correctly', () => {
const wrapper = mount( <MyModal modalOpen/> );
expect(wrapper).toMatchSnapshot();
// Passes
expect(wrapper.find('.outside')).toHaveLength(1);
// Construct new wrapper rooted at modal content
inside_els = document.getElementsByClassName("inside")[0]
inside_wrapper = new ReactWrapper(inside_els, true)
// Passes
expect(inside_wrapper.find('.inside')).toHaveLength(1);
});
目前,这是 open bug在 enzyme 中。
更新:测试完成后,Enzyme 似乎还会将模态附加到 DOM,因此您最终可能会在稍后的测试中打开多个对话框。如果这是一个问题,您可以在每次测试后清除 DOM,如下所示:
afterEach(() => {
var node = global.document.body;
while (node.firstChild) {
node.removeChild(node.firstChild);
}
});
关于reactjs - React 模式对话框的内容不可用于使用 mount() 的 enzyme 测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45644244/