web-dev-qa-db-fra.com

Comment déclencher un événement de modification sur les boutons radio dans react-testing-library?

Je suis en train de passer à react-testing-library, et je ne sais pas comment déclencher cet événement et obtenir les résultats des modifications.

J'ai essayé d'utiliser la fonction fireEvent pour déclencher le changement, puis j'ai essayé la fonction rerender, mais je n'arrive pas à le faire fonctionner.

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

});
8
jktravis

Tout d'abord, vous n'avez pas besoin d'appeler rerender. Vous utilisez rerender uniquement lorsque vous souhaitez que le composant reçoive des accessoires différents. Voir lien .

Chaque fois que vous appelez fireEvent, le composant sera rendu comme il le ferait dans votre application normale.

Il est correct de déclencher un événement change, mais vous devez passer un deuxième paramètre avec les données d'événement.

Cet exemple fonctionne:

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')
});
1
Giorgio Polvara - Gpx

Veuillez essayer ceci à partir de la documentation de react-testing-library, "render" devrait fonctionner correctement. D'accord avec @Gpx

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

J'ai aussi eu ce travail pour moi:

test('Does stuff', async () => {
// ... test prep ...

const formEl = screen.getByTestId('form_test_id')

// You can use screen.getByLabelText here instead of DOM queries 
// if you've got a nicely laid out form
const defaultInput = formEl.querySelector('input[value="default_value"]')
const newValueInput = formEl.querySelector('input[value="new_value"]')

// Confirm your baseline
expect(defaultInput.checked).toEqual(true)
expect(newValueInput.checked).toEqual(false)

// Fire the change event
await act(async () => {
fireEvent.change(newValueInput, { target: { checked: true } }) 
// To trigger any onChange listeners
fireEvent.blur(newValueInput)
})

// Confirm expected form state(s)
expect(defaultInput.checked).toEqual(false)
expect(newValueInput.checked).toEqual(true)

})
0
uch