3

Is there a clean way to be able to mock a child element when unit testing an element, using Mocha and friends?

For example, say I have something like this:

<Parent>
  <Child aProp={ this.props.clickChild() }/>
</Parent>

I want to mock it so I can manually trigger aProp and then tell that it called the clickChild that I passed it.

4
  • When you try to render Parent in your spec file, it already creates the Child. Scry for the Child and user trigger to invoke "aProp" Commented Mar 2, 2017 at 17:38
  • 1
    My point is, I want to prevent it from using the real Child and override what it does. This example is overly simplistic, but I'm thinking of scenarios where Child would be more complex and I want to sidestep all of that complexity. Commented Mar 2, 2017 at 18:14
  • Sounds like you are looking for dependency injection. Commented Mar 2, 2017 at 21:01
  • I sorta am, except React doesn't support it directly, which is a big distinguisher from Angular. I don't want to implement DI just to unit test. I was hoping there was a way to kind of half do it, but it looks like there isn't, at least with the class-style syntax. Commented Mar 2, 2017 at 23:39

1 Answer 1

4

After lots of research, it looks like this isn't really possible. If you do them in a very specific format, you can use certain mocking things, but you have to do several things which would be non-standard in your "real" code. I'm not a fan of modifying code for tests.

An alternative that I've settled on is for certain cases, I would just find the element after a mount(), get the property that provides the callback, and then trigger that directly and do whatever I need. Not a perfectly universal scenario, but it works.

Take this example code:

// Parent.js
export default class Parent extends React.Component {
    doSomething() {
        this.props.doSomethingTriggered();
    }

    render() {
        return <div>
            <Child onClick={ this.doSomething.bind() }/>
        </div>;
    }
}

I can use enzyme to mount the component, then trigger the onClick property of Child and spy on the callback I gave it to ensure it was called properly.

 it('should do something', () => {
      const callback = sinon.spy(() => {});
      const wrapper = mount(<Parent doSomethingTriggered={ callback }/>);
      wrapper.find(Child).props().onClick();
      sinon.assert.calledOnce(callback);
 });

Not quite mocking, but does let me bypass a good chunk of dependent code in certain scenarios.


Since this is a popular question, an update for Enzyme 16, it is now possible. You can now call instance() on any element and then call its function directly.

For example, take these examples:

class Parent extends React.Component {
  render() {
    return <div><Child /></div>
  }
}

class Child extends React.Component {
  render() { return <div>Hi</div> }

  doSomething() { }
}

With Enzyme 16, you can now do:

mount(<Parent />).find(Child).instance().doSomething()
Sign up to request clarification or add additional context in comments.

1 Comment

As a quick side note the access to instances only workd on Class components

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.