如何使用react酶检查实际的 DOM 节点

IT技术 javascript dom reactjs enzyme
2021-04-04 06:00:06

有没有办法获取实际的 DOM 节点,以便我可以使用 Dom api 查询它,而不是需要使用酶的 api,这仅适用于边缘情况,例如我需要断言有关 dom 节点本身的事情。

6个回答

您可以使用 wrapper.getDOMNode()

酵素文档

也许您正在寻找酶的instance()

const wrapper = mount(<input type="text" defaultValue="hello"/>)
console.log(wrapper.instance().value); // 'hello'

PS:

instance()应该给你一个ReactComponent,从中你可以使用 ReactDOM.findDOMNode(ReactComponent) 来获取一个 DOMNode。但是,当我这样做时,如下所示,它是与 完全相同的对象wrapper.instance()

import ReactDOM from 'react-dom'
const wrapper = mount(<input type="text" defaultValue="sup"/>)
console.log(ReactDOM.findDOMNode(wrapper.instance()) == wrapper.instance()) // true

我不明白为什么会这样。如果您console.log()是其中之一,您将看到一个HTMLInputElement,但它将包含许多非本机 DOM 节点外观的东西:

HTMLInputElement {
  '__reactInternalInstance$yt1y6akr6yldi': 
   ReactDOMComponent {
     _currentElement: 
      { '$$typeof': Symbol(react.element),
        type: 'input',
        key: null,
        ref: null,
        props: [Object],
        _owner: [Object],
        _store: {} },
是的,我使用的是 jsdom 9.1.0 - 抱歉我忘了提及
2021-05-28 06:00:06
我想知道是不是因为我在使用 jsdom(或者,我认为我是。愚蠢的我没有我运行的代码的永久链接)。你在使用 jsdom 吗?
2021-06-08 06:00:06
当我尝试您的技术时,它似乎按预期工作。换句话说,ReactDOM.findDOMNode(wrapper.instance()) != wrapper.instance()FWIW,我正在使用 React 15 和 Enzyme 2.3.0。
2021-06-22 06:00:06
这仅适用于根包装器(React 组件mount()ed 或shallow()ed)。有关更广泛适用的解决方案,请参阅 @tonyjmnz 的回答。
2021-06-22 06:00:06

我遇到了同样的问题。就我而言,我正在测试用 构建的东西react-aria-modal,它在 DOM 的不同部分呈现覆盖 div,而不是用 呈现的初始元素mount()为了测试这是否正确呈现,我需要更全面地查看 DOM。为此,我使用了attachTo选项render()来确保我的测试 DOM 在真实浏览器中看起来应该是这样。 是文档中对该技术的很好的一般描述。

根据您的需要,您可以对 DOM 的更多本地部分使用 Tyler Collier 的方法(findDOMNodeusing instance()),或者使用我的方法来获取更全局的视图。

这是我的用例的示例规范,展示了如何设置/使用/拆卸模拟 DOM:

import MyModalComponent from '../components/my-modal-component'
import React from 'react'
import { jsdom } from 'jsdom'
import { mount } from 'enzyme'

describe('<MyModalComponent /> Component', function(){

  let wrapper

  beforeEach(function(){
    window.document = jsdom('')
    document.body.appendChild(document.createElement('div'))
  })

  afterEach(function(){
    wrapper.detach()
    window.document = jsdom('')
  })

  it('renders the modal closed by default', () => {
    wrapper = mount(
      <MyModalComponent prop1={"foo"}
                        prop2={"bar"}
      />, { attachTo: document.body.firstChild }
    )
    expect(wrapper.html()).to.contain('Content in component')
    expect(document.body.innerHTML).to.not.contain('Content in overlay')
  })

})

如果您使用 jsdom 创建 DOM,则如下所示:

import jsdom from 'jsdom';
const doc = jsdom.jsdom('<!doctype html><html><body></body></html>');
global.document = doc;
global.window = doc.defaultView;

然后你可以使用酶的mount()来渲染你想要测试的任何东西。

然后,您可以针对您正在寻找的样式进行断言:

expect(wrapper).to.have.style("display", "none");

可能有更好的方法,但你总是可以调用.html()元素,然后使用类似的东西DOMParser()stackoverflow.com/questions/3103962/...
2021-05-24 06:00:06
据我所知,我正在使用使用 jsdom 的 mount,但是你将如何获得实际包装器的 DOM 节点以便我可以使用 dom api?例如查询 className 但使用 prop('className')
2021-06-22 06:00:06

你可以使用类似的东西:

const dialog = component.find(Modal);
let modal = dialog.node._modal;
modal.getDialogElement().querySelector('#saveBtn')

基于 react-bootstrap 网站中 Modal 的测试

https://github.com/react-bootstrap/react-bootstrap/blob/master/test/ModalSpec.js