Enzyme: Simulate click on component with no-string-refs callback

Created on 29 Aug 2016  ·  14Comments  ·  Source: enzymejs/enzyme

I am working on converting all my ref strings to ref callbacks, and trying to figure out how to handle my ref as a react component.

Since the callback returns a HTMLElement, I think I need to figure out how to render this as a react component? Can someone advise?

Previously, I could just do wrapper.ref('hello').simulate('click');

Code:

var Hello = React.createClass({
  componentDidMount: function() {
    var component = this.hello;
  },
  render() {
    return <div ref={(c) => { this.hello = c; }}>Hello, world.</div>;
  }
});

Test:

const wrapper = mount(<Hello />);
wrapper.node.hello.simulate('click');

Error:

TypeError: wrapper.node.hello.simulate is not a function

Most helpful comment

So is there any recommendation on how to use enzyme with ref callbacks?

All 14 comments

wrapper.instance().hello.simulate?

That is just a HTMLElement <div>Hello, world.</div>

simulate('click') on that would simply fire its onClick handler - what are you hoping will happen?

yeah that is what I am trying to accomplish, triggering the onClick handler using enzyme simulate.

You can not trigger enzyme simulate on the callback ref which is a HTMLElement. I assume this needs to get rendered into a ReactElement? Not sure how to go about this

In this case, wrapper is the div itself - does wrapper.simulate('click') not work?

I apologize, I guess i should have been more specific that I am trying to access it for a child node of the wrapper by accessing its ref.

<div><div ref={(c) => { this.hello = c; }}>Hello, world.</div></div>

So is there any recommendation on how to use enzyme with ref callbacks?

Any news here?

Not a great solution, but you can do:

wrapper.findWhere(n => n.node === wrapper.instance().hello).simulate();

I ended up adding this to a custom wrapper of enzyme wrapper (which fixes some other issues with find and findWhere) 🤦‍♂️

wrapper.findByRef = ref => {
  const refNode = wrapper.ref(ref);
  return wrapper.findWhere(node => {
    return node.getDOMNode() === refNode;
  });
};

now what used to be this:

wrapper.ref(nextButton).simulate('click');

can be written as:

wrapper.findByRef(nextButton).sumulate('click');

...which seems pretty clean and readable.

@ljharb is this something that could be useful for inclusion in enzyme?

@kangax (i'm not sure how this is relevant to simulate) string refs are deprecated, which is what .ref() works on.

ref callbacks involve users attaching their own instance properties, which you can already get at with wrapper.instance().refPropertyName. I'm not sure what more is needed here.

Separately, simulate should be avoided - it doesn't faithfully simulate anything, it's just sugar for invoking a prop function.

this was driving me bonkers. @kangax's solution was the best I could find. thanks for the suggestion!

It is better to put some id on it and do like this:
const wrapper = shallow()
wrapper.find('[id="inputfocus"]').simulate('click')

I definitely disagree - it's a very bad idea to put things in your code solely for the purpose of testing, ie, "test IDs" like you're suggesting.

Was this page helpful?
0 / 5 - 0 ratings