Why is useState not re-rendering the component in a unit test (Jest, Enzyme)?

Viewed 1211

I'm having trouble re-rendering an Enzyme-wrapped component in Jest. It took me a while to narrow down the problem, but it seems to be a problem with useState and Enzyme.

I have a component with a button in it. Clicking the button calls a setState() function to update component state and re-render. For example:

// ...
<Drawer
  classes={{ paper: classes.drawer }}
  anchor="right"
  open={showInfoDrawer}
  variant={mobile() ? 'temporary' : 'persistent'}
  onClose={() => {
    console.log('closing'); // to check onClose simulation works
    setShowInfoDrawer(false);
  }}
  >
  // rest of component...
</Drawer>
// ...

In this example, the setShowInfoDrawer() is part of a useState() hook, passed down as a prop from a parent component.

When I run a test (see example below), the click simulation seems to work, but the component does not re-render.

test('should close ActivityInfoDrawer', () => {
  expect(wrappedActivityInfoDrawer.find(Drawer)).toHaveLength(1);
  const wrappedDrawer = wrappedActivityInfoDrawer.find(Drawer);
  // @ts-ignore
  act(() => wrappedDrawer.props().onClose()); // Logs "Clicked..."
  wrappedActivityInfoDrawer.update();
  expect(wrappedActivityInfoDrawer.find(Drawer)).toHaveLength(0); // Fails
  });

I did some research and it seems that for a while Enzyme did not support useState, but it was address in this PR, which looks like it was released with version 3.11.0, or maybe even 3.10.0 (I'm using 3.11.0, the latest).

What am I doing wrong? Is it because setShowInfoDrawer() comes from a parent component? If so, how do I get it working?

1 Answers

Okay, I figured it out. It's pretty obvious in hindsight. I needed to running this test as a test for the parent component (ie, the component that opens the drawer and has the useState() hook), rather than as a unit test for the Drawer component itself.

Related