Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I trigger a change event on radio buttons in react-testing-library?

I'm in the process of moving over to react-testing-library, and have no idea how to trigger this event and get the results of the changes.

I've tried using the fireEvent function to trigger the change, and then tried the rerender function, but I can't seem to get it to work.

App.js

import React, { useState } from "react";
import logo from "./logo.svg";
import "./App.css";

const options = {
  DoTheThing: 'DoTheThing',
  DoOtherThing: 'DoOtherThing',
};

function App() {
  const [action, setAction] = useState(options.DoTheThing);

  return (
    <div className="App">
      <header className="App-header">
        <form>
          <fieldset>
            <label>
              <input
                type="radio"
                name="radio1"
                value={options.DoTheThing}
                checked={action === options.DoTheThing}
                onChange={event => setAction(event.target.value)}
              />
              First
            </label>

            <label>
              <input
                type="radio"
                name="radio1"
                value={options.DoOtherThing}
                checked={action === options.DoOtherThing}
                onChange={event => setAction(event.target.value)}
              />
              Second
            </label>
          </fieldset>
        </form>
      </header>
    </div>
  );
}

export default App;

App.test.js

import React from 'react';
import { render, cleanup, fireEvent } from 'react-testing-library';
import App from './App';

afterEach(cleanup);

it('should change the value ', () => {
  const {getByLabelText, rerender } = render(<App/>);
  const second = getByLabelText(/Second/);

  fireEvent.change(second);
  rerender(<App/>);

  expect(document.forms[0].elements.radio1.value).toEqual("DoOtherThing");

});
like image 490
jktravis Avatar asked Feb 15 '19 00:02

jktravis


People also ask

How do I test a radio button?

1 Answer. Show activity on this post. Radio buttons are meant to be used in groups, so that when clicking on one of them deselects the currently selected one. To test that a radio button is deselected simply select the other one.

Which function is used to firing event in React testing library?

createEvent[eventName] ​

What is the event for radio button?

A radio button fires the change event after you select it. How it works: First, register an event handler to the change event of the body . When a radio button is clicked, its change event is bubbled to the body.

How to trigger a change event in react?

There is no simple snippet to trigger React's change event. The logic is implemented in ChangeEventPlugin.js and there are different code branches for different input types and browsers. Moreover, the implementation details vary across versions of React.

How to use radio button input in react JS?

If you are new in react js then you want to see how to use radio button in react app. but it's very easy to use radio button input in react js app. you can use it as you use in html and you have to write change event on it. using that change event you have to store value into form state. so you can get that data on submit.

Should I use onchange or defaultchecked in react testing library?

You can't use defaultChecked though, because it stops you setting the state in code (i.e. clicking the button at the bottom doesn't update the radio) So on the whole, it looks like React wants you to use onChange but react-testing-library only works with onClick, so this is a bit of a fudge.

How React component can render different things?

We know that if React component can render different things, then it has to maintain state that tells it which thing to render. It's clear that our <input> component has 2 states to render: selected radio button and unselected radio button.


2 Answers

if you have a label like with Radio Component of Material-ui, you could use:

const labelRadio: HTMLInputElement = getByLabelText('Label of Radio');
expect(labelRadio.checked).toEqual(false);
fireEvent.click(labelRadio);
expect(androidRadio.checked).toEqual(true);

or you can add https://github.com/testing-library/jest-dom matchers and check it in this way:

expect(getByLabelText('Label of Radio')).not.toBeChecked();
fireEvent.click(labelRadio);
expect(getByLabelText('Label of Radio')).toBeChecked();
like image 165
andy Avatar answered Sep 19 '22 15:09

andy


First, you don't have to call rerender. You use rerender only when you want the component to receive different props. See link.

Whenever you call fireEvent the component will render like it would in your normal app.

It's correct to fire a change event, but you must pass a second parameter with the event data.

This example works:

import React from "react";
import { render, fireEvent } from "react-testing-library";

test("radio", () => {
  const { getByLabelText } = render(
    <form>
      <label>
         First <input type="radio" name="radio1" value="first" />
      </label>
      <label>
        Second <input type="radio" name="radio1" value="second" />
      </label>
    </form>
  );

  const radio = getByLabelText('First')
  fireEvent.change(radio, { target: { value: "second" } });
  expect(radio.value).toBe('second')
});
like image 35
Giorgio Polvara - Gpx Avatar answered Sep 20 '22 15:09

Giorgio Polvara - Gpx