title: Unit Testing image.onload and image.onerror Inside React.useEffect() With Jest and Enzyme
body: <p>I have the following component which displays an image when it is fully loaded:</p>
  <pre><code>export default function ImageDisplay(props: OwnPropsInterface): JSX.Element {
      const { src, alt, height, width } = props;
  
      const [image, setImage] = React.useState&lt;string&gt;('');
      const [showImage, setShowImage] = React.useState&lt;boolean&gt;(false);
      const [imageHeight, setImageHeight] = React.useState&lt;string&gt;('');
      const [imageWidth, setImageWidth] = React.useState&lt;string&gt;('');
  
      const setImageDimensions = () =&gt; {
          setImageHeight(
              typeof height === 'string' ? height : `${convertPixelsToRem(height)}rem`
          );
          setImageWidth(
              typeof width === 'string' ? width : `${convertPixelsToRem(width)}rem`
          );
      };
  
      const loadImageAsync = async () =&gt; {
          const image: HTMLImageElement = new Image();
  
          image.onload = () =&gt; {
              setImage(image.src);
              setShowImage(true);
          };
          image.onerror = (error) =&gt; {
              setShowImage(true);
          };
  
          image.src = src;
      };
  
      React.useEffect(() =&gt; {
          setImageDimensions();
          loadImageAsync();
      }, [src]);
  
      return (
          &lt;&gt;
              {showImage &amp;&amp; (
                  &lt;img
                      src={image}
                      alt={alt}
                      style={{ height: imageHeight, width: imageWidth }}
                  /&gt;
              )}
          &lt;/&gt;
      );
  }
  </code></pre>
  <p>I need to test <code>image.onload</code> and <code>image.onerror</code> and the subsequent behaviour of the component.</p>
  <p>Currently I have the below test written:</p>
  <pre><code>    describe('ImageDisplay', () =&gt; {
          let useEffect: jest.SpyInstance;
          let wrapper: ShallowWrapper;
  
          const mockUseEffect = () =&gt; {
              useEffect.mockImplementationOnce((f) =&gt; f());
          };
  
          beforeEach(() =&gt; {
              useEffect = jest.spyOn(React, 'useEffect').mockImplementation(() =&gt; {});
  
              mockUseEffect();
              mockUseEffect();
              wrapper = shallow(&lt;ImageDisplay {...imageDisplayProps} /&gt;);
          });
  
          describe('on load', () =&gt; {
              it('should set image props', () =&gt; {
                  expect(wrapper.find('img').props()).toEqual({
                      alt: 'test_alt',
                      src: '/test/src',
                      style: {
                          height: '100%',
                          width: '100%',
                      },
                  });
              });
          });
      });
  </code></pre>
  <p>The <code>expect</code> call fails with the below error:</p>
  <pre><code>Method “props” is meant to be run on 1 node. 0 found instead.
  
        115 |         describe('on load', () =&gt; {
        116 |             it('should set image props', () =&gt; {
      &gt; 117 |                 expect(wrapper.find('img').props()).toEqual({
            |                                            ^
        118 |                     alt: 'test_alt',
        119 |                     src: '/test/src',
        120 |                     style: {
  
        at ShallowWrapper.single (node_modules/enzyme/src/ShallowWrapper.js:1652:13)
        at ShallowWrapper.props (node_modules/enzyme/src/ShallowWrapper.js:1175:17)
        at Object.&lt;anonymous&gt; (test/unit-tests/components/ImageDisplay.component.test.tsx:117:44)
  </code></pre>
  <p>I understand that the <code>expect</code> is failing since it's executing immediately without waiting for the <code>image.onload</code> to finish and hence it's unable to find the <code>img</code> element.</p>
  <p>Is there a way to test the image events and the component behaviour? Really appreciate all the help. Thanks.</p>