简体   繁体   English

使用 React-Testing-Library 和 Jest 测试 useRef onError Fn

[英]Test useRef onError Fn, with React-Testing-Library and Jest

I have this simple fallbackImage Component:我有这个简单的 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;

It works perfectly.它完美地工作。 I have test running for it with Jest and React-Testing-Library .我使用JestReact-Testing-Library I have tested all but one scenario.除了一种场景之外,我已经测试了所有场景。 This one:这个:

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

This line basically prevents an infinite Loop in case both images are missing如果两个图像都丢失,这条线基本上可以防止无限循环

The Problem: I want to test that my onerror function has been called exactly one time.问题:我想测试我的onerror函数是否被调用了一次。 Which I am really stuck on how to do it.我真的被困在如何做到这一点上。 Here is the test...这里是测试...

      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.

The Question: How to access the ref callback function and check how many times has my function been called?问题:如何访问 ref 回调函数并检查我的函数被调用了多少次?

Any ideas on this.关于这个的任何想法。 I am at a loss, I tried mocking refs , I tried mocking and spying on the component.我不知所措,我试过嘲笑refs ,我试过嘲笑和监视组件。 I tried using act and async/await, in case it was called after.我尝试使用 act 和 async/await,以防它被调用。 I really need some help on this..我真的需要一些帮助。

You should check if your function is called or not, that's called testing implementation details, rather you should check if your img element have correct src.您应该检查您的函数是否被调用,这称为测试实现细节,而您应该检查您的 img 元素是否具有正确的 src。

Even you should add some alt and user getByAltText to select image element即使你应该添加一些 alt 和用户getByAltText来选择图像元素

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

You have 2 options:您有 2 个选择:

Add a callback to your props that will be called when whenImageIsMissing is called:将回调添加到您的道具中,该回调将在调用 whenImageIsMissing 时调用:

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} />
  );
};

and then insert jest.fn in your test and check how many times it was called.然后在你的测试中插入 jest.fn 并检查它被调用了多少次。

The other option is to take the implementation of whenImageIsMissing and put it inside image.util file and then use jest.spy to get number of calls.另一种选择是采用 whenImageIsMissing 的实现并将其放入 image.util 文件中,然后使用 jest.spy 获取调用次数。 Since you are using a function component there is no way to access this function directly.由于您使用的是函数组件,因此无法直接访问此函数。

Hope this helps.希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM