Jon*_*ray 7 unit-testing modal-dialog reactjs jestjs enzyme
我有一个带有模态对话框的React组件(使用构建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>
);
}
}
Run Code Online (Sandbox Code Playgroud)
我想像这样测试内容(在这种情况下使用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);
});
Run Code Online (Sandbox Code Playgroud)
测试正确地找到了Modal之外的内容,但是没有在里面找到任何内容.查看快照显示,实际上,内部没有任何<Modal>内容呈现.但是它确实,如果我更换工作mount用shallow.问题是我需要mount测试生命周期方法componentDidMount.
为什么不mount渲染模态的内容?我认为重点是它渲染了整个子元素树.
编辑:这在React 16 + Enzyme 3中不再是问题,因为React 16支持门户组件.
在React 15及之前,问题是模式对话框(在大多数实现中)是门户组件.这意味着它创建直接附加到文档根目录的DOM元素,而不是父React组件的子元素.
创建的find方法通过从顶级组件创建的元素开始查看DOM,因此无法找到模态的内容.但Enzyme 没有附加到DOM,而是构建自己的包含模态内容的组件树.ReactWrappermountshallow
要测试门户组件,首先需要找到已附加到文档主体的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);
});
Run Code Online (Sandbox Code Playgroud)
目前,这是Enzyme中的一个漏洞.
更新:似乎Enzyme在测试完成后也会将模态附加到DOM上,因此您可能会在稍后的测试中打开多个对话框.如果这是一个问题,您可以在每次测试后清除DOM,如下所示:
afterEach(() => {
var node = global.document.body;
while (node.firstChild) {
node.removeChild(node.firstChild);
}
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4568 次 |
| 最近记录: |