5

I've been teaching myself how to test react components with enzyme and jest, but I'm clueless as to how to test a mounted component which uses React hooks.

Here is a simplified version of the component...

  const [records, setRecords] = useState([]);

  const onChange = async ({ value }) => {
    try {
      const request = await searchRecords();

      console.log("Before setRecords");

      setRecords(request.results);

      console.log("After setRecords");
    } catch (error) {  /* error handling */ }
  }

The test code looks like...

let wrapped;

describe("Sample", () => {
  beforeEach(() => {
    jest.clearAllMocks();
    wrapped = mount(
      <Provider store={createStore(reducers, {})}>
        <Sample />
      </Provider>
    );
    api.mockImplementation(() => ({ results: searchResult }));
  });

  afterEach(() => {
    wrapped.unmount();
  });

  it("shows items in the search box", () => {
    wrapped.find("#searchField")
      .simulate("change", { target: { value: "blah blah" } });
    // This triggers "onChange" function

    wrapped.update();

    expect(wrapped.find("li").length).toEqual(10);  
    // If "setRecords()" hook works, there will be 10 "li" elements
  });
});

The test itself passes, but I see the following message in CLI.

Warning: An update to SearchBox inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped into act(...):

act(() => {
  /* fire events that update state */
});

Following the link provided in the warning message, I surrounded the lines which updated the state.

i.e.

act(() => {
  wrapped.find("#searchField").simulate("change", { target: { value: "red" } });
});

Still, the warning message persists. Just in case, I surrounded the mount(...) part, but it doesn't change anything.

In the test examples on React's doc, enzyme isn't used, so I feel like React Hooks are not compatible with enzyme.

How can we remove the warning message while still using enzyme? Or, is enzyme really incompatible?

Any advice will be appreciated.

AncientSwordRage
  • 7,086
  • 19
  • 90
  • 173
Hiroki
  • 3,893
  • 13
  • 51
  • 90
  • Have you tried to wrap mount function with act as well... Looking at the example even render function is wrapped with `act()`: https://reactjs.org/blog/2019/02/06/react-v16.8.0.html#testing-hooks – Maciej Trojniarz Sep 04 '19 at 21:05
  • I'm also seeing this, with seemingly no reason – AncientSwordRage Oct 22 '20 at 11:35
  • I had a similar issue. You need to post more of your component as I suspect that something async is called where/when you haven't wrapped it. – AncientSwordRage Jun 05 '21 at 12:00
  • 1
    Any updates on this? I'm having the same issues - all tests pass, but I get this error message for each instance of `expect` that I have in my test file. I've wrapped everything in `act(()` and `act(async()` etc. – Duderino9000 Feb 03 '22 at 02:13
  • 1
    @barryman9000 when I've had it there was a 'hidden' update in my non-simplified version of the component. I don't think I could find it now though, so I'm not sure I could answer this either. – AncientSwordRage Feb 03 '22 at 02:56
  • 1
    @Barryman9000 I stopped using Enzyme and started to use react-testing-library – Hiroki Feb 05 '22 at 07:51

0 Answers0