1
votes

Testing a React function component, this component on form submit calls a helper API function which I mocked.

Below code gives me Warning: An update to SomeComponent inside a test was not wrapped in act(...). and does not update state of component.

Component Pseudo Code

import React, { memo }  from "react"

import { apiFunc } from "./API";

function SomeComponent() {
    onSubmit = async () => {
        const response = await apiFunc();

        // DO something with response
    }

    return (
        <form onSubmit={onSubmit}>
            <input type="text" />
        </form>
    )
}

export default memo(SomeComponent)

Jest API mock "API/__mocks__/API"

export const apiFunc = () => {
    return Promise.resolve({ message: "Success" });
};

Jest test

jest.mock("./API")

describe("<SomeComponent />", () => {
    it("Submits form", () => {
        const wrapper = mount(<Component />);

        wrapper
            .find(`input[aria-label="${TEXTS.EMAIL}"]`)
            .simulate("change", { target: { value: "[email protected]" } });

        wrapper.find("form").simulate("submit");

        expect(wrapper.find("div.fp-success")).toHaveLength(1);
    });
});
2

2 Answers

0
votes
describe('Scoped / Nested block', () => {
  beforeAll(() => {
    global.fetch = jest.fn().mockImplementation(() => //your function );
  });
  afterAll(() => {
    global.fetch.mockClear();
    delete global.fetch;
  });
  //your it

}
0
votes

The solution was wrapping the submit in act as in below and calling force state update

Also you need react-dom 16.9 and above to use async act.

jest.mock("./API")

describe("<SomeComponent />", async () => {
    it("Submits form", () => {
        const wrapper = mount(<Component />);

        wrapper
            .find(`input[aria-label="${TEXTS.EMAIL}"]`)
            .simulate("change", { target: { value: "[email protected]" } });

        await act(async () => {
            wrapper.find("form").simulate("submit");
        });

        act(() => {
            wrapper.update();
        });

        expect(wrapper.find("div.fp-success")).toHaveLength(1);
    });
});

Hope this helps other devs looking for solution