Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

like image 734
Simon Long Avatar asked Apr 30 '20 16:04

Simon Long


People also ask

Which is better Enzyme or Jest?

Many people choose to use Jest and Enzyme together to test their React web applications. They use Jest as a test runner and assertion library, then use Enzyme to build the tests for their UI. This results in slimmer, cleaner testing code that's also easier to debug when a test breaks.

What is difference between Jest and Enzyme?

While they are used in this context to test react components, Jest is not specific to React, and can be used in other JavaScript applications. Enzyme however is a tool which is specific to React.

Can I use Jest without Enzyme?

Jest can be used without Enzyme, and snapshots can be created and tested perfectly fine. But the Enzyme adds additional functionality to it. An enzyme can also be used without Jest, but we need any other test runner paired with it. Jest:- Jest as a test runner, assertion library, and mocking library.

How do I use the material UI checkbox?

The Material UI Checkbox works by using the browser's native input HTML element, inside of a Material UI IconButton to create the ripple and button effects. The native checkbox input is hidden and instead a checkbox SVG icon (or a custom icon of your choice) is used. This is a fairly simple component. How to set a Material UI Checkbox

How do I test text input in enzyme?

Testing text input is relatively simple. First mount the component with Enzyme’s mount function, then set the value and simulate the change. When there are multiple input fields, we can use .at (0) to find the input element by index. For checkbox, assign the value for checked instead of value and then simulate change.

How to test multi-select with checkbox and select elements?

For checkbox, assign the value for checked instead of value and then simulate change. To test multi-select, you need to set the individual option’s selected property to true. This solution works. Simulating change on the select element as below doesn’t work.

How do you check if a checkbox is checked or not?

You have a checked prop, a boolean set to either true or false , which determines whether the Checkbox is checked or not. You use the onChange prop and React hooks to set and maintain the state of the checkbox. In the event handler, we can look at event.target.checked to know what the new state value should be set to.


1 Answers

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.

like image 96
Martin Dawson Avatar answered Sep 30 '22 13:09

Martin Dawson