【问题标题】:Test useRef onError Fn, with React-Testing-Library and Jest使用 React-Testing-Library 和 Jest 测试 useRef onError Fn
【发布时间】:2020-05-14 17:17:47
【问题描述】:

我有这个简单的 fallbackImage 组件:

export interface ImageProps {
  srcImage: string;
  classNames?: string;
  fallbackImage?: FallbackImages;
}

const Image = ({
  srcImage,
  classNames,
  fallbackImage = FallbackImages.FALLBACK
}: ImageProps) => {
  const imgToSourceFrom = srcImage;
  const imgToFallbackTo = fallbackImage;

  const imageRef = useRef(null);
  const whenImageIsMissing = () => {
    imageRef.current.src = imgToFallbackTo;
    imageRef.current.onerror = () => {};
  };

  return (
    <img ref={imageRef} src={imgToSourceFrom} className={classNames} onError={whenImageIsMissing} />
  );
};

export default Image;

完美运行。我使用JestReact-Testing-Library 对其进行了测试。除了一种情况外,我已经测试了所有情况。这个:

  const whenImageIsMissing = () => {
    imageRef.current.src = imgToFallbackTo;
    imageRef.current.onerror = () => {}; // This line.
  };

这条线基本上可以防止两个图像都丢失的无限循环

问题: 我想测试我的onerror 函数是否被调用了一次。我真的很想怎么做。这是测试...

      const { container } = render(<Image srcImage={undefined} fallbackImage={undefined} />);

      const assertion = container.querySelector('img').onerror;

      fireEvent.error(container.firstElementChild);

      console.log(container.firstElementChild);
      expect(container.firstElementChild.ref.current.onerror).toHaveBeenCalledTimes(1);
      // This though has no reference to a real value. Is an example of what I want to get at.

问题: 如何访问 ref 回调函数并查看我的函数被调用了多少次?

对此有任何想法。我不知所措,我尝试嘲笑refs,我尝试嘲笑和监视组件。我尝试使用 act 和 async/await,以防它被调用。我真的需要一些帮助..

【问题讨论】:

    标签: reactjs typescript unit-testing react-hooks react-testing-library


    【解决方案1】:

    你应该检查你的函数是否被调用,这叫做测试实现细节,而不是你应该检查你的img元素是否有正确的src。

    即使您应该添加一些 alt 和用户 getByAltText 来选择图像元素

    const { getByAltText } = render(<Image srcImage={undefined} fallbackImage={undefined} />);
    const imageElement = getByAltText('Image Alt');
    fireEvent.error(imageElement);
    expect(imageElement.src).toEqual(imgToFallbackTo);
    

    【讨论】:

    • 是的,我有点理解。我已经测试过了。但是我的代码在那里有一个守卫。我不应该检查一下吗?我的意思是,如果我删除了这行代码并且我没有回退,我就会进入一个无限循环。所以,至少对我来说,这似乎是一个合适的测试场景。你觉得呢??
    【解决方案2】:

    你有两个选择:

    在调用 whenImageIsMissing 时为你的 props 添加一个回调:

    export interface ImageProps {
      srcImage: string;
      classNames?: string;
      fallbackImage?: FallbackImages;
      onImageMissing?:();
    }
    
    const Image = ({
      srcImage,
      classNames,
      onImageMissing,
      fallbackImage = FallbackImages.FALLBACK
    }: ImageProps) => {
      const imgToSourceFrom = srcImage;
      const imgToFallbackTo = fallbackImage;
    
      const imageRef = useRef(null);
      const whenImageIsMissing = () => {
        imageRef.current.src = imgToFallbackTo;
        imageRef.current.onerror = () => {};
        if (onImageMissing) onImageMissing();
      };
    
      return (
        <img ref={imageRef} src={imgToSourceFrom} className={classNames} onError={whenImageIsMissing} />
      );
    };
    

    然后在您的测试中插入 jest.fn 并检查它被调用了多少次。

    另一种选择是执行 whenImageIsMissing 并将其放入 image.util 文件中,然后使用 jest.spy 获取调用次数。由于您使用的是函数组件,因此无法直接访问此函数。

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 2020-03-22
      • 2021-02-11
      • 2021-02-28
      • 2020-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多