Enzyme: Find via Props for Mounted Components

Created on 11 May 2016  路  9Comments  路  Source: enzymejs/enzyme

Within a mounted component, I am trying to differentiate between like elements by evaluating the difference in props. I.e. two <Link/> elements that differ by URL path:

Component JSX:

<LeftDrawer {...props} >
  <Link to="/">Link Name</Link>
  <Link to="/another-place">Another Link Name</Link>
</LeftDrawer>

This works (shallow):

const wrapper = shallow(<LeftDrawer {...minProps} />);
expect(
        wrapper.find({ to: '/' }).length
      ).toEqual(1);

This fails (mount):

const wrapper = mount(<LeftDrawer {...minProps} />);
expect(
        wrapper.find({ to: '/' }).length // Expected 0 to equal 1
      ).toEqual(1);

This works (shallow):

const wrapper = shallow(<LeftDrawer {...minProps} />);
expect(
       wrapper.find('Link[to="/"]').text()
      ).toEqual('Link Name');

This fails (mount):

const wrapper = mount(<LeftDrawer {...minProps} />);
expect(
       wrapper.find('Link[to="/"]').text() // This method is only meant to be run on single node. 0 found instead.
      ).toEqual('Link Name');
bug

Most helpful comment

@DanielRamosAcosta findWhere is more verbose but does the job just fine:

wrapper.findWhere(node => node.props().to === '/')

All 9 comments

I was able to reproduce the issue with find({to: '/'}) for mount here.

@joncursi so the reason you're seeing this disparity is because mount checks the props against the returned DOM node. So, for example, if your to prop is being rendered as an href value on an anchor element, doing:

wrapper.find({href: '/'})

would work. Shallow checks against the instances actual props instead, which is why its working. The mount API is typically used to validate the render output against a DOM, so it makes some sense that there's a disparity here. On the other hand, it's less confusing if both find() worked as similarly as possible.

@lelandrichardson what do you think? Should the find() API be consistent here?

@Aweary hmm, running that snippet on a mounted component didn't work for me:

const wrapper = mount(<LeftDrawer {...minProps} />);

expect(
  wrapper.find({ href: '/' }).length // Expected 0 to equal 1
).toEqual(1);

And yes, <Link /> is a small component that passes it's to prop as an href to a child <a></a> tag.

can someone post a gist of a basic test case here? From what I see in this issue, this sounds like a bug. You should be able to call find('[to="foo"]') on a ReactWrapper and have it find something if there is a higher order component like <Link to="foo" /> in the render tree. If it doesn't, that's wrong.

@lelandrichardson you can see an example here: https://github.com/Aweary/enzyme-test-repo/blob/issue-%23376/test.js

There is an isDOMComponent check that is being called in instMatchesObjectProps which is returning false for the MockLink instances. I'm guessing that's probably the issue.

@lelandrichardson I added this failing test case on my branch

    it('should probably not break with MockLink (?)', () => {

      class MockLink extends React.Component {
        render() {
          const to = this.props.to;
          const children = this.props.children;
          return (
            <a href={to}>{children}</a>
          );
        }
      }

      const wrapper = mount(
        <div>
          <MockLink to="/">First</MockLink>
          <MockLink to="/second">Second</MockLink>
        </div>
      );

      expect(wrapper.find({ to: '/' })).to.have.length(1);

    });

isDOMComponent is returning false for MockLink. If I just do propsOfNode(inst) it's returning their props just fine.

Hi guys, do you know if there is any workaround while this issue gets fixed? Thanks!

@DanielRamosAcosta findWhere is more verbose but does the job just fine:

wrapper.findWhere(node => node.props().to === '/')

I'm going to close this; please file a new issue if it's still a problem on v3.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

nelsonchen90 picture nelsonchen90  路  3Comments

heikkimu picture heikkimu  路  3Comments

andrewhl picture andrewhl  路  3Comments

timhonders picture timhonders  路  3Comments

AdamYahid picture AdamYahid  路  3Comments