How do I trigger a change event on radio buttons i

2020-04-04 15:06发布

问题:

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");

});

回答1:

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')
});


回答2:

Please try this from react-testing-library docs, "render" should work fine. Agree with @Gpx

fireEvent.change(input, { target: { value: 'your_value_goes_here' } })
expect(input.value).toBe('expected_value')