我有以下组件:
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/