reactjs - 如何测试使用 enzyme 改变 useState 状态的点击事件?

标签 reactjs testing jestjs enzyme

我有以下组件:

import React, { useState } from "react";

import { Button, ThirteenBold } from "@selfdecode/sd-component-library";
import { PlayIcon } from "assets/icons";
import { TourButtonProps } from "./interfaces";
import { WelcomeVideoModal } from "../../modals/welcome-video-modal";

/**
 * The tour button.
 */
export const TourButton: React.FC<TourButtonProps> = (props) => {
  const [isIntroVideoShowing, setIsIntroVideoShowing] = useState(false);

  return (
    <>
      <WelcomeVideoModal
        isOpen={isIntroVideoShowing}
        onClickX={() => setIsIntroVideoShowing(false)}
        data-test="tour-button-welcome-video"
      />

      <Button
        {...props}
        width={["max-content"]}
        variant="tour"
        onClick={() => setIsIntroVideoShowing(true)}
        data-test="tour-button"
      >
        <ThirteenBold
          mr={["12px"]}
          color="cl_blue"
          width={["max-content"]}
          letterSpacing={["1px"]}
          display={["none", "block"]}
          textTransform="uppercase"
        >
          welcome tour
        </ThirteenBold>

        <PlayIcon style={{ height: "30px", fill: "#4568F9" }} />
      </Button>
    </>
  );
};

测试覆盖率报告提示我没有测试两个改变状态的 onClick 事件。

我尝试了两种方法,但都失败了。 方法一是模拟 useState 并查看它是否按照我的预期被调用。 这是我尝试过的测试:

 const setState = jest.fn();
 const useStateMock: any = (initState: any) => [initState, setState];
 jest.spyOn(React, "useState").mockImplementation(useStateMock);
 
 const button = wrapper.find(`[data-test="tour-button"]`);
 expect(button).toHaveLength(1);
 button.simulate("click");
 expect(setState).toHaveBeenCalled();

这甚至不应该是最终的测试,因为它不会检查调用它的值是什么,但它仍然失败,因为甚至没有调用 useState。

我尝试的第二种方法是检查此组件上的 prop 值:

 <WelcomeVideoModal
    isOpen={isIntroVideoShowing}
    onClickX={() => setIsIntroVideoShowing(false)}
    data-test="tour-button-welcome-video"
 />

这是我尝试过的测试

  test("Check the isIntroVideoShowing changes to true on buton click", () => {
    jest.spyOn(React, "useState").mockImplementation(useStateMock);
    const button = wrapper.find(`[data-test="tour-button"]`);
    const welcomeVideo = wrapper.find(
      `[data-test="tour-button-welcome-video"]`
    );
    expect(button).toHaveLength(1);
    expect(welcomeVideo.prop("isOpen")).toEqual(false);
    button.simulate("click");
    expect(welcomeVideo.prop("isOpen")).toEqual(true);
  });

即使在点击之后,这个也失败了,声称它被调用为 false。

有办法让这些工作发挥作用吗?或者用不同的方法来涵盖这些?

最佳答案

模拟点击事件后,您需要提供wrapper.update来更新模板的状态变化。

test("Check the isIntroVideoShowing changes to true on buton click", () => {
    jest.spyOn(React, "useState").mockImplementation(useStateMock);
    const button = wrapper.find(`[data-test="tour-button"]`);
    const welcomeVideo = wrapper.find(
      `[data-test="tour-button-welcome-video"]`
    );
    expect(button).toHaveLength(1);
    expect(welcomeVideo.prop("isOpen")).toEqual(false);
    button.simulate("click");
    wrapper.update();
    expect(welcomeVideo.prop("isOpen")).toEqual(true);
  });

引用 - https://enzymejs.github.io/enzyme/docs/api/ShallowWrapper/update.html

关于reactjs - 如何测试使用 enzyme 改变 useState 状态的点击事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65406678/

相关文章:

reactjs - 如何将缓存恢复到初始状态

javascript - React-router 5.2 无法从 URL 获取参数

php - Laravel 测试页面上元素的顺序

string - 双方括号和单方括号 [ 和 [[ 以及等号 = 和 == 有什么区别?

javascript - 在 AngularJS 应用程序中测试使用 Protractor 将文件上传到文件选择器

javascript - 使用特定 Prop 进行连接组件测试(React/Redux)

reactjs - 通过 react 路由器时隐藏 id 或查询字符串

reactjs - 如何解码来自 Axios、React 的 json 请求

javascript - Jest Uncovered Lines - 我如何测试这些线..?

javascript - Firebase 模拟器可以用于与 React 前端的集成测试吗?