如何在 react-testing-library 中的单选按钮上触发更改事件?

新手上路,请多包涵

我正在转移到 react-testing-library,并且不知道如何触发此事件并获得更改的结果。

我尝试使用 fireEvent 函数来触发更改,然后尝试了 rerender 函数,但我似乎无法让它工作。

应用程序.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;

应用程序.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");

});

原文由 jktravis 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 683
2 个回答

更新

正如人们指出的那样,我原来的解决方案是错误的。

现在我建议你使用 userEvent 来更好地模拟用户交互。

 import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";

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

  await user.click(screen.getByLabelText("Second"));
});


首先,您不必调用 rerender 。仅当您希望组件接收不同的道具时才使用 rerender 。见 链接

每当您调用 fireEvent 时,组件都会像在普通应用程序中一样呈现。

触发 change 事件是正确的,但您必须传递带有事件数据的第二个参数。

这个例子有效:

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

原文由 Giorgio Polvara - Gpx 发布,翻译遵循 CC BY-SA 4.0 许可协议

如果你有一个像 Material-ui 的 Radio Component 这样的标签,你可以使用:

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

或者您可以添加 https://github.com/testing-library/jest-dom 匹配器并以这种方式检查它:

 expect(getByLabelText('Label of Radio')).not.toBeChecked();
fireEvent.click(labelRadio);
expect(getByLabelText('Label of Radio')).toBeChecked();

原文由 andy 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进