RTL测试按钮onClick属性失败,请求排查解决
我在用React Testing Library测试Button组件时,始终无法通过onClick属性的测试。已模拟onClick函数,却收到以下错误:
expect(jest.fn()).toHaveBeenCalledTimes(expected) Expected number of calls: 1 Received number of calls: 0
测试代码
import React from 'react' import { render, screen, fireEvent } from '@testing-library/react' import '@testing-library/jest-dom' import Button from "../Button/Button" const handleClick = jest.fn(); describe('Button', () => { beforeEach(() => { render( <Button onClick={handleClick} > buttonText </Button> ) }) it('should render button text', () => { const buttonText = "buttonText" expect(screen.getByText(buttonText)).toBeInTheDocument() }) it('calls onClick prop when clicked', () => { const handleClick = jest.fn(); const buttonText = "buttonText" fireEvent.click(screen.getByText(buttonText)) expect(handleClick).toHaveBeenCalledTimes(1) }) })
Button组件代码
import React from "react"; import { PrimaryButton } from "./Button.styles"; const Button = ({ onClick, children }) => ( <PrimaryButton type="button" onClick={onClick} > {children} </PrimaryButton> ); export default Button;
解决方案
问题根源是测试用例calls onClick prop when clicked内部重新声明了handleClick变量,覆盖了外部定义的模拟函数。实际绑定到Button组件上的是外部的handleClick,但你断言的是测试用例内部新创建的、从未被调用的函数,所以会出现调用次数为0的错误。
修改后的测试代码如下:
import React from 'react' import { render, screen, fireEvent } from '@testing-library/react' import '@testing-library/jest-dom' import Button from "../Button/Button" describe('Button', () => { let handleClick; beforeEach(() => { // 每个测试用例前重新初始化模拟函数,避免用例间互相干扰 handleClick = jest.fn(); render( <Button onClick={handleClick} > buttonText </Button> ) }) it('should render button text', () => { const buttonText = "buttonText" expect(screen.getByText(buttonText)).toBeInTheDocument() }) it('calls onClick prop when clicked', () => { const buttonText = "buttonText" fireEvent.click(screen.getByText(buttonText)) expect(handleClick).toHaveBeenCalledTimes(1) }) })
说明
- 将
handleClick的声明移到describe块内部,在beforeEach中每次创建新的jest模拟函数,保证每个测试用例的独立性,避免测试用例之间的状态污染。 - 删除测试用例内部的
const handleClick = jest.fn();,直接使用beforeEach中初始化的模拟函数,确保断言的就是绑定到Button组件上的那个函数。
内容的提问来源于stack exchange,提问作者njouro
相关产品推荐
相关产品推荐

