Jest.js 如何等到动画结束才测试点击回调?

2sbarzqh  于 2023-10-14  发布在  Jest
关注(0)|答案(1)|浏览(107)

我已经创建了一个react组件,当单击它时,它会执行一个动画,动画结束后,会运行一个回调。我想使用Jest和react测试库来测试这个功能。这是我的组件:

export const Valuable = ({ onClick }) => {
  const [isClicked, setIsClicked] = useState(false);
  const handleClick = () => {
    setIsClicked(true);
  };
  const handleAnimationEnd = () => {
    setIsClicked(false);
    onClick();
  };

  return (
    <div
      className={isClicked ? 'animate-valuable ' : ''}
      onClick={handleClick}
      onAnimationEnd={handleAnimationEnd}
      data-testid="valuable-container"
    >
      ...
    </div>
  );
};

测试:

describe('Valuable', () => {
  const valuableProps = {
    onClick: jest.fn(),
  };
  beforeEach(() => {
    render(<Valuable {...valuableProps} />);
  });

  it('should execute on click callback', () => {
    expect(valuableProps.onClick).not.toHaveBeenCalled();
    const container = screen.getByTestId('valuable-container');
    expect(container).toBeInTheDocument();
    fireEvent.click(container);
    expect(valuableProps.onClick).toBeCalledTimes(1);
    fireEvent.click(container);
    fireEvent.click(container);
    expect(valuableProps.onClick).toBeCalledTimes(3);
  });
});

这是我得到的错误

● Valuable › should execute on click callback

    expect(jest.fn()).toHaveBeenCalledTimes(expected)

    Expected number of calls: 1
    Received number of calls: 0
pcrecxhr

pcrecxhr1#

我的假设是您正在jsdom环境中运行测试。根据React测试库设置文档:
然而,大多数使用React测试库的人都将其与Jest测试框架一起使用,其中testEnvironment设置为jest-environment-jsdom(这是Jest 26及更早版本的默认配置)。jsdom是在Node中运行的DOM和浏览器API的纯JavaScript实现。
如果是这样,the animationend event is not supported in jsdom
你可以通过显式的firing the animationend event来解决它:

it('should execute on click callback', () => {
    expect(valuableProps.onClick).not.toHaveBeenCalled();
    const container = screen.getByTestId('valuable-container');
    expect(container).toBeInTheDocument();
    fireEvent.click(container);
    expect(valuableProps.onClick).toBeCalledTimes(0);
    fireEvent.animationEnd(container);
    expect(valuableProps.onClick).toBeCalledTimes(1);
    fireEvent.click(container);
    fireEvent.animationEnd(container);
    fireEvent.click(container);
    fireEvent.animationEnd(container);
    expect(valuableProps.onClick).toBeCalledTimes(3);
  });

相关问题