如何测试调用 setState 函数的 onClick 事件所做的更改,该函数从另一个组件传递并更改 UI?

How to test changes made by onClick event that calls a setState function, which is passed from another component and changes UI?

基本上是标题。

这里是 App 的概述:

const App = () => {
  const [isViewFavoriteImages, setIsViewFavoriteImages] = useState(false);

  const toggleIsViewFavoriteImages = () => {
    setIsViewFavoriteImages(
      (prevToggleIsViewFavoriteImagesState) =>
        !prevToggleIsViewFavoriteImagesState
    );
  };

  return (
    <div className="App">
      <div className="container">
        <ToggleImagesViewButton
          toggleIsViewFavoriteImages={toggleIsViewFavoriteImages}
          isViewFavoriteImages={isViewFavoriteImages}
        />
        <ImageList isViewFavoriteImages={isViewFavoriteImages} />
      </div>
    </div>
  );
};

export default App;

按钮组件:

export interface ToggleImageViewButtonProps {
  toggleIsViewFavoriteImages: () => void;
  isViewFavoriteImages: boolean;
}

const ToggleImageViewButton: React.FC<ToggleImageViewButtonProps> = ({
  toggleIsViewFavoriteImages,
  isViewFavoriteImages,
}) => {
  return (
    <button
      onClick={toggleIsViewFavoriteImages}
      className="btn btn_toggle-image-view"
      data-testid="toggle-image-view"
    >
      {isViewFavoriteImages ? "view all" : "view favorites"}
    </button>
  );
};

export default ToggleImageViewButton;

这就是我测试它的方式:

function renderToggleImagesViewButton(
  props: Partial<ToggleImageViewButtonProps> = {}
) {
  const defaultProps: ToggleImageViewButtonProps = {
    toggleIsViewFavoriteImages: () => {
      return;
    },
    isViewFavoriteImages: true,
  };
  return render(<ToggleImageViewButton {...defaultProps} {...props} />);
}

describe("<ToggleImagesViewButton />", () => {
  test("button inner text should change to 'view all' when the user clicks the button", async () => {
    const onToggle = jest.fn();

    const { findByTestId } = renderToggleImagesViewButton({
      toggleIsViewFavoriteImages: onToggle,
    });

    const toggleImagesViewButton = await findByTestId("toggle-image-view");

    fireEvent.click(toggleImagesViewButton);

    expect(toggleImagesViewButton).toHaveTextContent("view favorites");
  });
});

此测试失败,"view all" 仍会返回。

ToggleImageViewButton 没有内部状态 - 状态被提升到父级,因此测试状态更改应该发生在父级的测试中。

您可以进行以下集成测试来验证按钮在 App 中使用时的正确行为。

test("App test", () => {
    render(<App />);
    const button = screen.getByTestId("toggle-image-view");
    expect(button).toHaveTextContent("view favorites");
    fireEvent.click(button);
    expect(button).toHaveTextContent("view all");
});

至于 ToggleImageViewButton 单元测试,您可以简单地测试它是否根据 isViewFavoriteImages 值呈现正确的文本,以及是否在单击按钮时调用回调。

test("ToggleImageViewButton test", () => {
    const onToggle = jest.fn();
    render(<ToggleImageViewButton isViewFavoriteImages={false} toggleIsViewFavoriteImages={onToggle}/>);
    expect(screen.getByTestId("toggle-image-view")).toHaveTextContent("view favorites");
    fireEvent.click(screen.getByTestId("toggle-image-view"));
    expect(onToggle).toHaveBeenCalled();
});