酶:如何测试具有DOM副作用的组件?

时间:2019-04-08 10:07:28

标签: reactjs jestjs enzyme

说我有一个像这样的组件-

// @flow

import React, { PureComponent } from 'react';


export default class ReplaceLink extends Component {
  containerRef = React.createRef();

  componentDidMount() {
    const links = 
      Array.from(this.containerRef.current.getElementsByTagName('a'));
    links.forEach(a => a.setAttribute('href', 'dummylink'));
  }

  render = () => <div ref={this.containerRef}>{this.props.children}</div>;
}

替换其中放置的链接的href。但是,即使在酶中进行完整的dom渲染时,当我执行wrapper.debug()以查看渲染结果时,我仍然仅看到原始链接。

我尝试过强制wrapper.update并使用setTimeouts,但这只是没有反映出预期的链接。

2 个答案:

答案 0 :(得分:0)

React中不鼓励直接DOM访问的原因之一是它使测试更加复杂。

可以使用跳过的componentDidMount渲染组件:

const wrapper = shallow(<ReplaceLink/>, { disableLifecycleMethods: true })

然后可以模拟ref并手动调用componentDidMount

const setAttribute = jest.fn();
const getElementsByTagName = jest.fn().mockImplementation(() => [{ setAttribute }]);

wrapper.instance().containerRef.current = { getElementsByTagName };
wrapper.instance().componentDidMount();

然后可以断定存根的DOM函数被调用。

答案 1 :(得分:0)

找到一种测试类似内容的最佳方法是通过getDOMNode方法。

  1. 首先,请确保使用mount来渲染包装器,因此我们有一个模拟的DOM环境可供查询。

  2. 接下来,使用wrapper.getDOMNode()获取基础的DOM节点。

  3. 在生命周期方法中对基础DOM所做的任何更改都将反映在此DOM参考中。
  4. 使用.querySelector<insert-dom-query-method>进行断言。

    const wrapper = mount(
      <ReplaceLink> 
        <a href="gogole.com"> Google</a> 
      </ReplaceLink>
    );
    
    const linkTags = wrapper.getDOMNode().querySelectorAll('a');
    
    linkTags.forEach(tag => {
      expect(tag.getAttribute('href')).toBe('dummy');
    });