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 ...
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.
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.
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.
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
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With