4

I am trying to complete a jest test on a bespoke reusable component but having difficulty getting it to work. I have pared it back in a sandbox using plain material-ui components and am still having difficulty in simulating the radio button click. I have tried

     wrapper.find(Radio).first().simulate('click');
     wrapper.find(Radio).first().prop('onChange', { target: { checked: true } });
     wrapper.find(Radio).first().simulate('change', {target: {checked: true}});
     wrapper.find(Radio).first().update();

working sandbox with failing test here: https://codesandbox.io/s/magical-raman-7f8v7

complete code file here:


import React from "react";
import { mount } from "enzyme";
import { RadioGroup, Radio } from "@material-ui/core";
import { configure } from "enzyme";
import Adapter from "enzyme-adapter-react-16";
import FormControlLabel from "@material-ui/core/FormControlLabel";
import FormControl from "@material-ui/core/FormControl";
import FormLabel from "@material-ui/core/FormLabel";

configure({ adapter: new Adapter() });

const TestComponentRadioGroup = () => {
  const [value, setValue] = React.useState("other");
  const handleChange = event => {
    setValue(event.target.value);
  };

  return (
    <div>
      <FormControl component="fieldset">
        <FormLabel component="legend">Gender</FormLabel>
        <RadioGroup
          aria-label="gender"
          name="gender1"
          value={value}
          onChange={handleChange}
        >
          <FormControlLabel value="female" control={<Radio />} label="Female" />
          <FormControlLabel value="male" control={<Radio />} label="Male" />
          <FormControlLabel value="other" control={<Radio />} label="Other" />
        </RadioGroup>
      </FormControl>
    </div>
  );
};

describe("---RadioGroup Interaction Test Suite", () => {
  test("Test to check selection isupdated from the last option to the first ", () => {
    const wrapper = mount(<TestComponentRadioGroup />);

    const radioButtonGroup = wrapper.find(RadioGroup);
    expect(radioButtonGroup).toHaveLength(1);

    //check that the first item isn't checked but the third one is
    const radioButtons = wrapper.find(Radio);
    console.log("we found " + radioButtons.length + " radiobuttons");
    expect(radioButtons).toHaveLength(3);

    expect( wrapper.find(Radio).first().props().checked).toBe(false);
    expect( wrapper.find(Radio).last().props().checked).toBe(true);

    //Desperation - I expected the first one to work!
    wrapper.find(Radio).first().simulate("click");
    wrapper.find(Radio).first().prop("onChange", { target: { checked: true } });
    wrapper.find(Radio).first().simulate("change", { target: { checked: true } });
    wrapper.find(Radio).first().update();

    //I am not sure that I need this!
    wrapper.update();

    expect( wrapper.find(Radio).first().props().checked).toBe(true);
    expect( wrapper.find(Radio).last().props().checked).toBe(false);
  });
});

Community
  • 1
  • 1
tmc
  • 404
  • 1
  • 7
  • 20

2 Answers2

3

and react-testing library this will do the work for you. I am using data-test-id to target the radio input.

it("Radio group change value and new value updated and last value no more checked", () => {
    const { container, getByTestId } = render(<FilterRadioButtonGroup {...props} />);

    // Before change selection
    const allValueRadioButton = getByTestId('radio-button-all');
    expect(allValueRadioButton.checked).toEqual(true);

    // Change selection
    const withValueRadioButton = getByTestId('radio-button-with');
    fireEvent.click(withValueRadioButton, { target: { checked: true }});
    expect(withValueRadioButton.checked).toEqual(true);

    // Old value is no more checked
    expect(allValueRadioButton.checked).toEqual(false);
});

if you also use material-ui use the inputProps prop, in order to get data-test-id showed. (As their props accepting).

<Radio
size={size}
disabled={item.disabled}
inputProps={{
    "data-testid": `radio-button-${item.text}`,
}}/>

If you not using material-ui no need for the inputProps just directly data-testid

:)

Ido Bleicher
  • 709
  • 1
  • 9
  • 19
  • do I _need_ another library? why can't jest see the simulated click by itself? TIA – tmc Sep 15 '20 at 21:36
  • If the radio button on the form causes side-effects, you should use `userEvent.click(button)` instead of `fireEvent...` because it is a higher-level event and allows code to run. – Matt Aug 08 '23 at 02:48
1

This code is working for me:

import { Radio } from '@material-ui/core';

let mComponent: ReactWrapper;
mComponent = mount(component);

const radioInputs = mComponent.find(Radio);
radioInputs.at(0).simulate('click', { target: { checked: true } });
  • Thank you for sharing. Would you mind editing your answer to include an explanation of what you’re doing and why it addresses the issue? – Jeremy Caney May 18 '20 at 00:10