Ad

Enzyme: How Can I Test A Component With DOM Side-effect?

- 1 answer

Say I have a component like so -

// @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>;
}

which replaces href of links placed within it. But even when doing full dom rendering in enzyme, when I do a wrapper.debug() to see the result of the render, I still see original links only.

I've tried doing a force wrapper.update and using setTimeouts, but it just doesn't reflect the expected link.

Ad

Answer

Found the best way to test something like this is through the getDOMNode method.

  1. First, make sure to use mount to render the wrapper, so we have a simulated DOM environment to query against.

  2. Next, use wrapper.getDOMNode() to get the underlying DOM node.

  3. Any changes made during the lifecycle methods to the underlying DOM will be reflected in this DOM reference.
  4. Use .querySelector, or <insert-dom-query-method> to make assertions.

    const wrapper = mount(
      <ReplaceLink> 
        <a target="_blank" rel="nofollow noreferrer" href="gogole.com"> Google</a> 
      </ReplaceLink>
    );
    
    const linkTags = wrapper.getDOMNode().querySelectorAll('a');
    
    linkTags.forEach(tag => {
      expect(tag.getAttribute('href')).toBe('dummy');
    });
    
Ad
source: stackoverflow.com
Ad