Skip to content

useEffect not called when the component is shallow renderered #2086

@jlandic

Description

@jlandic

Current behavior

useEffect fonction does not seem to be executed when the component is rendered with shallow.

Given the following simple component using useEffect hook to call a method given as a prop:

import React, { useEffect } from 'react';

export const MyComponent = ({ callback }) => {
  useEffect(() => {
    callback('Say something');
  });

  return <div>Hello world!</div>;
};

And the following tests checking that the callback function is indeed called accordingly:

import React from 'react';
import { shallow, mount } from 'enzyme';
import { MyComponent } from '../MyComponent';

describe('MyComponent', () => {
  describe('shallow render', () => {
    it('should call callback when shallow rendered', () => {
      const callback = jest.fn();
      shallow(<MyComponent callback={callback} />);
      expect(callback).toHaveBeenCalled();
    });
  });

  describe('mount', () => {
    it('should call callback when mounted', () => {
      const callback = jest.fn();
      mount(<MyComponent callback={callback} />);
      expect(callback).toHaveBeenCalled();
    });
  });
});

We observe that the method is called as expected when "mounted", but not when using a shallow renderer:

 FAIL  src/tests/MyComponent.test.js
  MyComponent
    shallow render
      ✕ should call callback when shallow rendered (12ms)
    mount
      ✓ should call callback when mounted (24ms)

  ● MyComponent › shallow render › should call callback when shallow rendered

    expect(jest.fn()).toHaveBeenCalled()

    Expected mock function to have been called, but it was not called.

       8 |       const callback = jest.fn();
       9 |       shallow(<MyComponent callback={callback} />);
    > 10 |       expect(callback).toHaveBeenCalled();
         |                        ^
      11 |     });
      12 |   });
      13 |

      at Object.toHaveBeenCalled (src/tests/MyComponent.test.js:10:24)

You may find this reproducible example here.

Expected behavior

When using shallow to render the components, the function passed to useEffect should be executed, as it is when using mount.

Your environment

API

  • shallow
  • mount
  • render

Version

library version
enzyme 3.9.0
react 16.8.6
react-dom 16.8.6
react-test-renderer 16.8.6
adapter (below)

Adapter

  • enzyme-adapter-react-16
  • enzyme-adapter-react-16.3
  • enzyme-adapter-react-16.2
  • enzyme-adapter-react-16.1
  • enzyme-adapter-react-15
  • enzyme-adapter-react-15.4
  • enzyme-adapter-react-14
  • enzyme-adapter-react-13
  • enzyme-adapter-react-helper
  • others ( )

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions