reactjsunit-testingjestjschakra-uireact-test-renderer

Is there a way to test Chakra-ui modal dialogs with react-test-renderer?


I'm desperately trying to test a modal but can't get my head around it!

This is where I'm at:

expect(
  create(
    <PortalManager>
      <Modal isOpen={true} onClose={jest.fn()}>
        <ModalOverlay />
        <ModalContent>
          <ModalHeader>Modal Title</ModalHeader>
          <ModalCloseButton />
          <ModalBody>Modal body</ModalBody>
          <ModalFooter>Modal footer</ModalFooter>
        </ModalContent>
      </Modal>
    </PortalManager>,
  ).toJSON(),
).toMatchSnapshot();

I forced the modal to be opened. I added the PortalManager around it to make sure Chakra knows where to place the modal but snapshot is always empty.


Solution

  • Well, an option may be to mock PortalManager itself and make it act like a React.Component instead of a React.ReactPortal, so something like

    const divWithChildrenMock = (children, identifier) => <div data-testId={identifier}>{children}</div>;
    const divWithoutChildrenMock = (identifier) => <div data-testId={identifier} />;
    
    jest.mock("@chakra-ui/react", () => (
      {
        ...jest.requireActual("@chakra-ui/react"),
        PortalManager: jest.fn(({ children }) => divWithChildrenMock(children, "portal")),
        Modal: jest.fn(({ children }) => divWithChildrenMock(children, "modal")),
        ModalOverlay: jest.fn(({ children }) => divWithChildrenMock(children, "overlay")),
        ModalContent: jest.fn(({ children }) => divWithChildrenMock(children, "content")),
        ModalHeader: jest.fn(({ children }) => divWithChildrenMock(children, "header")),
        ModalFooter: jest.fn(({ children }) => divWithChildrenMock(children, "footer")),
        ModalBody: jest.fn(({ children }) => divWithChildrenMock(children, "body")),
        ModalCloseButton: jest.fn(() => divWithoutChildrenMock("close")),
      }
    ));
    
    

    By looking at the following source file

    https://github.com/chakra-ui/chakra-ui/blob/main/packages/modal/src/modal.tsx

    You can see that even the modal components uses Portal, so, you should mock these components too, as in the example.

    Test id is useful in the tests to check, in the snapshots, if all components are rendered in the right order.