web-dev-qa-db-ja.com

反応テストライブラリのラジオボタンで変更イベントをトリガーするにはどうすればよいですか?

私は現在、反応テストライブラリに移動している最中であり、このイベントをトリガーして変更の結果を取得する方法がわかりません。

fireEvent関数を使用して変更をトリガーしてから、rerender関数を試してみましたが、機能しないようです。

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

まず、rerenderを呼び出す必要はありません。 rerenderは、コンポーネントが異なる小道具を受け取るようにする場合にのみ使用します。 link を参照してください。

fireEventを呼び出すと、コンポーネントは通常のアプリと同じようにレンダリングされます。

changeイベントを発生させるのは正しいことですが、イベントデータとともに2番目のパラメーターを渡す必要があります。

この例は機能します:

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

「レンダリング」は問題なく機能するはずです。react-testing-librarydocsからこれを試してください。 @Gpxに同意する

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

私もこの仕事をしてきました:

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