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

应用程序.测验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所在元素的首选方法是什么?非常感谢.

推荐答案

这是关于RTL:D被问到最多的问题

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

关于为什么这是最好的方法的更多信息,我也写了一些适用于这个 case 的东西.OP询问了一个 Select material 界面,但 idea 是一样的.

我的答案是:

因为你无法控制这个用户界面.它在第三方模块中定义.

所以,你有两个 Select :

您可以找出material 库创建的HTML,然后使用容器.querySelector查找其元素并与之交互.这需要一段时间,但应该是可能的.在完成所有这些之后,您必须希望在每一个新版本中,它们不会太多地更改DOM struct ,否则您可能需要更新所有测试.

另一个 Select 是相信Material UI将制作出一个有效且用户可以使用的组件.基于这种信任,您可以在测试中简单地替换该组件,以获得更简单的组件.

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

根据我的经验,第二种 Select 很好,但当然,您的用例可能不同,您可能需要测试实际的组件.

这是一个如何模拟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>
  );
});

你可以读here多本书.

Reactjs相关问答推荐

如何使用mui为可重复使用的react 按钮应用不同的风格

NextJs Form不允许我输入任何输入,

如何在React中的textarea中显示字符数?

将动态元素中的输入数据传输到Reaction

有没有办法将在服务器端全局获取的一些数据传递到Next&>13应用程序目录中的客户端组件?

更改购物车中的产品数量后,PayPal Reaction/Next JS按钮未更新

在transformResponse中使用来自其他查询的缓存

为什么React UseEffect挂钩在页面重新加载时运行

如何在中间件中获取 nextAuth 会话

滚动视图样式高度没有任何区别

生产部署:控制台中 Firebase 无效 api 密钥错误

ReactJS:在导航栏中使用 Select inside Link 组件时如何避免重定向?

在react 中从外部 api 渲染列表

来自一个自定义 React Native 组件的样式从另一个自定义组件移除样式

setState 改变对象引用

React Router v6 - 访问嵌套路由和处理手写 url 的正确方法

单击三个按钮之一后如何显示特定按钮的内容?单击其中一个按钮后应隐藏所有按钮

多次响应获取发送请求

我可以在类组件中使用 useState 挂钩吗?

可以'读取未定义的属性(读取'路径')