CodeNewbie Community 🌱

Tim Rohrer
Tim Rohrer

Posted on

How should I test the closing of a popup menu?

I'm a noob when it comes to testing React components. I suspect I may be approaching this all wrong, and my lack of mastery of the DOM could be playing a role in my current troubles.

So how am I trying to test this today? Let's take a simple example of a menu that I wish to display in my mui-based app. For simplicity, the menu has one option: "Import Data".

   <div>
      <Button
        id="basic-button"
        aria-controls={open ? "basic-menu" : undefined}
        aria-haspopup="true"
        aria-expanded={open ? "true" : undefined}
        onClick={handleClick}
      >
        Main Menu
      </Button>
      <Menu
        id="basic-menu"
        anchorEl={anchorEl}
        open={open}
        onClose={handleClose}
        MenuListProps={{
          "aria-labelledby": "basic-button"
        }}
      >
        <MenuItem onClick={handleImport}>Import Data</MenuItem>
      </Menu>
    </div>
Enter fullscreen mode Exit fullscreen mode

MUI displays text with <span> elements so I pass a function to queryByText to perform matches, but the gist of the test is pretty straightforward:

test("The menu popup closes when the option is selected", async () => {
  renderTestComponent();

  await userEvent.click(screen.getByRole("button"));
  await userEvent.click(screen.getByText("Import Data"));

  expect(screen.queryByText(textContentMatcher(/Import Data/))).toBeNull();
});
Enter fullscreen mode Exit fullscreen mode

First I render the component, then I simulate clicking on the menu button followed by the "Import Data" option. These steps work without errors.

However, my assertion fails because "Import Data" is still found in the rendered screen. Shouldn't this clear out when the menu is closed?

If I move the assertion before the button is clicked, the test passes.

I suspect I am misunderstanding how the rendering is done. The actual code does work as expected, so this issue is related specifically to my understanding and implementation of the test.

How should I approach this test?

The code

Top comments (5)

Collapse
 
asy13 profile image
ASY13

I’m facing a similar issue but slightly different not too sure how testing works, Regardless thanks for being brave enough to post your code and hope someone is able to jump in and help.

Collapse
 
timrohrer profile image
Tim Rohrer Author

Hey--

I did end up getting a test working, but as I recall I also revamped the approach for the component. If you think it will be of help to you, I'll update the sandbox?

Or, if you've got one of your own I'd be willing to take a look at it.

Collapse
 
asy13 profile image
ASY13

That would be so helpful thanks!

Thread Thread
 
asy13 profile image
ASY13

I’m trying to simply test that a row is being added into a dynamic table ( I have 11 elements in a JSON already so the 12 signifies a brand new row )

});
test('adds a row on click', () => {
render();
const clickBtn = screen.getByTestId(12);
fireEvent.click(clickBtn);
expect(clickBtn.textContent).toBe(12);

});
But not sure how to format the test 🥹

Thread Thread
 
timrohrer profile image
Tim Rohrer Author

I’m not experienced enough to look at a single block of code and be able to judge a good approach to a test. If you assemble a working example at CodeSandbox, I might be able to play around with a fork and see what works. That would also help a reader see the error being generated.

I started to write some other thoughts, but realized they were based on assumptions about your situation that simply couldn’t be substantiated yet :-)

Please put together a sandbox.