How Can I Test an MUI ToggleButtonGroup with a userEvent?

1k Views Asked by At

I am using MUI ToggleButtonGroup component like so:

<ToggleButtonGroup
        color="primary"
        value={mode}
        exclusive
        onChange={changeHandler}
        fullWidth
        className="mt-4"
      >
        <ToggleButton value="login">Login</ToggleButton>
        <ToggleButton value="register">Register</ToggleButton>
      </ToggleButtonGroup>

When clicking the 'Register' button, it works fine in the UI. I'd like to get a proper test written with React Testing Library.

Here's what I have:

setup();
    heading = screen.getByRole("heading", { level: 2 });
const registerButton = screen.getByRole("button", { name: /register/i });
    userEvent.click(registerButton);

    expect(heading).toHaveTextContent("Register");

The crux of the issue seems to be that userEvent.click somehow doesn't call the changeHandler. Is there some type of bubbling or something that I need to concern myself with?

Here's a prettyDOM log of the relevant components:

 <button
      aria-pressed="false"
      class="MuiButtonBase-root MuiToggleButton-root MuiToggleButton-fullWidth MuiToggleButton-sizeMedium MuiToggleButton-primary MuiToggleButtonGroup-grouped MuiToggleButtonGroup-groupedHorizontal css-j4p6el-MuiButtonBase-root-MuiToggleButton-root"
      tabindex="0"
      type="button"
      value="register"
    >
      Register
      <span
        class="MuiTouchRipple-root css-8je8zh-MuiTouchRipple-root"
      />
    </button> <h2
      class="MuiTypography-root MuiTypography-h5 css-ag7rrr-MuiTypography-root"
    >
      Login
    </h2>
2

There are 2 best solutions below

0
user20989184 On

Add an id to the component: <ToggleButton id={${data.value}}> {data.label}

test case:

describe("ToggleButtonGroupComponent onChange Testing", () => {
    const onChange = vi.fn();
    it("toggle group change value and new value updated and last value no more checked", () => {
        const { container } = render(<ToggleButtonGroupComponent {...props} onChange={onChange} />);
        // Before change selection
        const allValueToggleButton = QueryAttributeById(container, "ssh") as HTMLInputElement;
        expect(allValueToggleButton.value).toEqual("ssh");
        // Change selection
        const withValueToggleButton = QueryAttributeById(container, "http") as HTMLInputElement;
        fireEvent.click(withValueToggleButton);
        expect(withValueToggleButton.value).toEqual("http");
        // Old value is no more checked
        expect(allValueToggleButton.value).toEqual("ssh");
    });
});
0
Laurence Lord On

My experience is that userEvent.click(el) doesn't work but calling el.click() does.