如何使用 React 测试库测试输入?

Gre*_*fan 6 typescript reactjs jestjs react-testing-library

我正在尝试通过 React 测试库测试组件input的值Search

搜索组件接收两个属性:handleChangeinput value: title

我的目标是编写测试,以便最初输入值为空,当用户键入内容时,测试可以验证监听事件值是否正确,但它始终获取初始值。

我试图在键入之前清除输入,但它不起作用。

错误是:

 Expected the element to have value:
                       // indicates as empty string which I expect
                    
    Received:
      test            // it is still the default value: `test`, UserEvent.clear didn't clear
Run Code Online (Sandbox Code Playgroud)

这是两个测试,首先检查输入最初是否为空,这工作正常,第二个测试监听输入。

import { fireEvent, screen, waitFor } from "@testing-library/react";
import Search from "../Search";
import { render } from "../../../test-utils/test-utils";
import "@testing-library/jest-dom";
import userEvent from "@testing-library/user-event";

const mockedOnChange = jest.fn();

describe("input should be filled with title", () => {
  test("input should be empty initially", async () => {
    render(<Search title="" onChangeHadler={mockedOnChange} />);
    const input = screen.getByRole("textbox", { name: /search/i });
    expect(input).toHaveValue("");
  });
   // renderComponent wrapps the `Search` component
  const renderComponent = (searchInputValue: string) => {
    const view = render(
      <Search title={searchInputValue} onChangeHadler={mockedOnChange} />
    );
    return view;
  };

  test("input should update by typed text", async () => {
    renderComponent("test");
    const input = await screen.findByRole("textbox", { name: /search/i });
    await waitFor(() => expect(input).toHaveValue("test"));
    userEvent.clear(input);
    expect(input).toHaveValue(""); // error appears here indicating that value was not cleared

    // userEvent.type(input, "su"); 
    // await waitFor(() => expect(input).toHaveValue("su"));
  });
});
Run Code Online (Sandbox Code Playgroud)

Flo*_*Flo 6

您的测试组件是受控组件:它从父组件接收(支持)其值,并带有一个函数引用,该函数引用通知父组件用户更改了输入值。通常,此函数将更新父状态,该状态会向下传递给子组件,并用作输入值。

在您的测试中,您仅渲染子组件,并模拟回调函数。因此,您不能期望在测试中触发用户交互时输入值会发生变化。您只能测试titleprops 是否用作输入的值,以及触发用户交互时是否正确调用回调函数(在测试中模拟)。但是,如果不渲染父组件,则无法测试“完整场景”。

test("input value is the title props", async () => {
    renderComponent("test");
    const input = await screen.findByRole("textbox", { name: /search/i });
    await waitFor(() => expect(input).toHaveValue("test"));
});

test("callback function is called on user interactions", async () => {
    renderComponent("test");
    const input = await screen.findByRole("textbox", { name: /search/i });
    userEvent.type(input, "new value");
    expect(mockedOnChange).toHaveBeenCalledWith("new value");
});
Run Code Online (Sandbox Code Playgroud)

  • ...是的,您可以通过测试父组件来测试完整的场景。尽管请记住,对子组件进行适当的单元测试仍然是相关的,特别是如果子组件要在另一个上下文中使用不同的父组件(不太可能,但仍然如此) (2认同)