React, Jest and Material-UI: How to test for content rendered in a modal or popover

前端 未结 2 1242
[愿得一人]
[愿得一人] 2021-02-14 19:12

There are a few material-ui components that do not render their results in the same place as the component is placed by their parent. Among these we have the Dialog

相关标签:
2条回答
  • 2021-02-14 19:45

    Yes this can be tricky. The issue is two-fold:

    1. firing a click event means you need to make your test an async function
    2. the menu items are not in your wrapper element <AppMenu /> - as you noted they are elsewhere in the DOM.

    For the menu items, you'll need to locate them where they actually are. The button that opens the menu is in your wrapper element, but the menu and the menu items won't be, so you'll need to get the menu by role then you can get the items within menu by their text.

    Here's an example of how I'd do this using React Testing Library.

    import React, { ReactElement } from "react";
    import { render, screen } from "@testing-library/react";
    import AppMenu from "./AppMenu";
    import { getByText, fireEvent, getByLabelText } from "@testing-library/react";
    
    
    test("It renders some menu items", async () => {
      const { container } = render(<AppMenu />);
      const button = getByText(container, "Menu");
    
      fireEvent.click(button);
    
      const menuItem = screen.getByRole("menu");
    
      expect(await getByLabelText(menuItem, "Home")).toBeTruthy();
      expect(await getByLabelText(menuItem, "Sign in")).toBeTruthy();
    });
    
    0 讨论(0)
  • 2021-02-14 19:51

    The Menu won't be rendered until state changes, so you can simulate a click on the Button, let its handler setState, trigger a rerender, and find the specific MenuItem.

    Also, this can probably be done without fully mounting:

    it('renders some menu items', () => {
      const wrapper = shallow(<AppMenu />);
    
      // find the Menu Button
      const button = wrapper.findWhere(node => node.is(Button) && n.prop('children') === 'Menu');
    
      // simulate a click event so that state is changed
      button.simulate('click');
    
      // find the Home MenuItem
      const menuItem = wrapper.findWhere(node => node.is(MenuItem) && n.prop('label') === 'Home');
    
      // make sure it was rendered
      expect(menuItem.exists()).toBe(true);
    });
    
    0 讨论(0)
提交回复
热议问题