如何使用react-testing-library测试react-select [英] how to test react-select with react-testing-library

查看:265
本文介绍了如何使用react-testing-library测试react-select的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

App.js

import React, { Component } from "react";
import Select from "react-select";

const SELECT_OPTIONS = ["FOO", "BAR"].map(e => {
  return { value: e, label: e };
});

class App extends Component {
  state = {
    selected: SELECT_OPTIONS[0].value
  };

  handleSelectChange = e => {
    this.setState({ selected: e.value });
  };

  render() {
    const { selected } = this.state;
    const value = { value: selected, label: selected };
    return (
      <div className="App">
        <div data-testid="select">
          <Select
            multi={false}
            value={value}
            options={SELECT_OPTIONS}
            onChange={this.handleSelectChange}
          />
        </div>
        <p data-testid="select-output">{selected}</p>
      </div>
    );
  }
}

export default App;

App.test.js

App.test.js

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

afterEach(cleanup);

const setup = () => {
  const utils = render(<App />);
  const selectOutput = utils.getByTestId("select-output");
  const selectInput = document.getElementById("react-select-2-input");
  return { selectOutput, selectInput };
};

test("it can change selected item", async () => {
  const { selectOutput, selectInput } = setup();
  getByText(selectOutput, "FOO");
  fireEvent.change(selectInput, { target: { value: "BAR" } });
  await waitForElement(() => getByText(selectOutput, "BAR"));
});

这个最小的示例在浏览器中可以正常工作,但是测试失败.我认为没有调用onChange处理程序.如何在测试中触发onChange回调?查找fireEvent元素的首选方法是什么?谢谢

This minimal example works as expected in the browser but the test fails. I think the onChange handler in is not invoked. How can I trigger the onChange callback in the test? What is the preferred way to find the element to fireEvent at? Thank you

推荐答案

这必须是有关RTL的最常见问题:D

This got to be the most asked question about RTL :D

最好的策略是使用 jest.mock (或测试框架中的等效项)来模拟选择并呈现HTML选择.

The best strategy is to use jest.mock (or the equivalent in your testing framework) to mock the select and render an HTML select instead.

有关为什么这是最好的方法的更多信息,我也写了一些适用于这种情况的内容. OP询问了Material-UI中的选择,但是想法是一样的.

For more info on why this is the best approach, I wrote something that applies to this case too. The OP asked about a select in Material-UI but the idea is the same.

因为您无法控制该UI.它是在第3方模块中定义的.

Because you have no control over that UI. It's defined in a 3rd party module.

因此,您有两个选择:

您可以找出材质库创建的HTML,然后使用container.querySelector查找其元素并与其进行交互.这需要一段时间,但应该可以.完成所有这些操作后,您必须希望在每个新发行版中,它们不要过多地更改DOM结构,否则您可能必须更新所有测试.

You can figure out what HTML the material library creates and then use container.querySelector to find its elements and interact with it. It takes a while but it should be possible. After you have done all of that you have to hope that at every new release they don't change the DOM structure too much or you might have to update all your tests.

另一个选择是相信Material-UI将使组件能够正常工作并且您的用户可以使用.基于这种信任,您只需在测试中替换该组件即可.

The other option is to trust that Material-UI is going to make a component that works and that your users can use. Based on that trust you can simply replace that component in your tests for a simpler one.

是的,选项一测试用户看到的内容,但是选项二更易于维护.

Yes, option one tests what the user sees but option two is easier to maintain.

根据我的经验,第二个选项很好,但是当然,您的用例可能有所不同,您可能必须测试实际的组件.

In my experience the second option is just fine but of course, your use-case might be different and you might have to test the actual component.

这是一个如何模拟选择的示例:

This is an example of how you could mock a select:

jest.mock("react-select", () => ({ options, value, onChange }) => {
  function handleChange(event) {
    const option = options.find(
      option => option.value === event.currentTarget.value
    );
    onChange(option);
  }
  return (
    <select data-testid="select" value={value} onChange={handleChange}>
      {options.map(({ label, value }) => (
        <option key={value} value={value}>
          {label}
        </option>
      ))}
    </select>
  );
});

您可以在此处 a>.

这篇关于如何使用react-testing-library测试react-select的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆