How to toggle and check a Material UI Checkbox in Enzyme / Jest Test
Asked Answered
P

2

8

I've got a simple component wrapped around a Material UI Checkbox. I've stripped it down to the bare minimum here.

//@flow
import React from "react";
import { Checkbox } from "@material-ui/core";

function MyCheckboxComponent() {
  const [checkedState, setCheckedState] = React.useState(true);

  const handleChange = event => {
    setCheckedState(event.target.checked);
  };

  return <Checkbox checked={checkedState} onChange={handleChange} />;
}

export default MyCheckboxComponent;

I simply want to test this component and toggle the Checkbox value and check it. I cannot get my simple test passing. I'm at a loss as to why.

import React from "react";

import Enzyme, { mount } from "enzyme";
import { Checkbox } from "@material-ui/core";
import Adapter from "enzyme-adapter-react-16";

import MyCheckboxComponent from "./MyCheckboxComponent";
Enzyme.configure({ adapter: new Adapter() });

/** Interaction tests testing user interaction with PilzButton */
test("Toggle Checkbox test", () => {
  const wrapper = mount(<MyCheckboxComponent />);

  const checkBox = wrapper.find(Checkbox);
  expect(checkBox).toHaveLength(1);

  checkBox.simulate('change', { target: { checked: true } });

  expect(checkBox.props().checked).toBe(true);
});

Should checkBox.simulate('change', { target: { checked: true } }); work and toggle the value of the Checkbox ??

What I have so far is here on CodeSandbox ...

Edit toggle-material-ui-checkbox-jest

Parturition answered 30/4, 2020 at 16:2 Comment(0)
P
6

Newest versions of enzyme cache the results returned from find and other methods.

You need to re-find and also use .update() to force the refresh of the state to re-render.

  const checkBox = wrapper.find(Checkbox);
  expect(checkBox).toHaveLength(1);

  checkBox.simulate('change', { target: { checked: true } });

  wrapper.update();

  expect(wrapper.find(Checkbox).props().checked).toBe(true);

Also, this may just be because you wanted to produce a minimal reproducible question but your test is poor at the moment because your default value is true and you are passing true in dynamically.

You should do this instead:

  const checkBox = wrapper.find(Checkbox);
  expect(checkBox).toHaveLength(1);
  expect(checkBox.props().checked).toBe(true);

  checkBox.simulate('change', { target: { checked: false } });

  wrapper.update();

  expect(wrapper.find(Checkbox).props().checked).toBe(false);

This test is actually proving that the onChange works properly now.

Pneuma answered 30/4, 2020 at 17:46 Comment(0)
F
1

const checkBox = wrapper.find(Checkbox);
  expect(checkBox).toHaveLength(1);
  expect(checkBox.props().checked).toBe(false);

 checkBox.prop("onChange")({ currentTarget: { checked: true } });

  wrapper.update();

  expect(wrapper.find(Checkbox).props().checked).toBe(true);

Just a minor update to the answer above. The checkbox state doesn't change with "simulate" and instead works with "prop" for me.

Fogel answered 4/11, 2021 at 1:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.