我有一个带有模态对话框的Reaction组件(使用reactstrap
,但其他人也报告了类似的问题react-bootstrap
以及其他类型的模态部件)。酶在模态中找不到任何成分,即使它们在实际的应用程序中呈现得很好。最起码的例子:
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
渲染模态的内容?我认为关键在于它呈现了整个子元素树。
这意味着它创建了直接附加到文档根的DOM元素,而不是父响应组件的子元素。
由mount
从顶层组件创建的元素开始查看DOM,因此找不到模型的内容。但酶shallow
不附加到DOM,而是构建自己的组件树,其中包含模态内容。
要测试门户组件,首先需要找到附加到文档主体的DOM元素。然后您可以创建一个新的ReactWrapper
在它们周围,所有通常的酶功能都能发挥作用:
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);
});
更新:似乎酶也会在测试结束后将模式附加到DOM,因此在以后的测试中可能会打开多个对话框。如果这是一个问题,您可以在每次测试之后清除DOM,如下所示:
afterEach(() => {
var node = global.document.body;
while (node.firstChild) {
node.removeChild(node.firstChild);
}
});