rareyesdev
rareyesdev

Reputation: 2427

Test image onload inside react component using enzyme, sinon

I'm trying to test that a function callback is being called for an image inside my component.

This is the component:

const ImageById = (props) => {
  return (
    <div>
      <img src={props.url} onLoad={props.onLoad} onError={props.onError} />
    </div>
  );
};

And my test mounts the component and then spy the callback function:

describe('ImageById', () => {
  it('should call load or error', () => {
    let callbackSpy = sinon.spy();
    let comp = mount(ImageById, {url: 'some-url', onLoad: callbackSpy, onError: callbackSpy});
    expect(callbackSpy.called).to.equal(true);
  });
});

The test fails because the inner Img tag is never calling its onload nor onerror methods. In production the code is working fine, it might be something related to the test environment. Its like Img tag doesn't react to the url being set.

Upvotes: 2

Views: 1659

Answers (1)

rareyesdev
rareyesdev

Reputation: 2427

I discovered that mounting the component doesn't causes load and error events to occur. I found a way of simulate them using TestUtils like this:

var Wrapper = React.createClass({
  render: function () {
    return (
      <div>{this.props.children}</div>
    );
  },
  propTypes: {
    children: PropTypes.object
  }
});

describe('ImageById', () => {
  it('should call load or error', () => {
    let callbackSpy = sinon.spy();
    // need to wrap `Images` inside a class component because `renderIntoDocument`
    // wont render pure functional components.
    // https://github.com/facebook/react/issues/4692#issuecomment-163029873
    var component = TestUtils.renderIntoDocument(<Wrapper><ImageById url={'some-url'} onLoad={callbackSpy} onError={callbackSpy} /></Wrapper>);
    var image = TestUtils.findRenderedDOMComponentWithTag(component, 'img');
    TestUtils.Simulate.load(image);
    expect(callbackSpy.called).to.equal(true);
  });
});

Upvotes: 3

Related Questions