Тестирование useRef onError Fn, с библиотекой React-Testing-Library и Jest

У меня есть этот простой компонент 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;

Работает отлично. У меня есть тестовый запуск с Jest и React-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, если он был вызван после. Мне действительно нужна помощь в этом ..


person Dimitris Efst    schedule 29.01.2020    source источник


Ответы (2)


Вы должны проверить, вызывается ли ваша функция или нет, это называется деталями реализации тестирования, вместо этого вы должны проверить, имеет ли ваш элемент 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);
person Amit Chauhan    schedule 29.01.2020
comment
Да, я вроде понимаю это. Это я уже испытал. Но у моего кода есть охранник. Разве я не должен это проверить? Я имею в виду, что если я удалю эту строку кода и у меня не будет выхода, я попаду в бесконечный цикл. Так что, мне, по крайней мере, это кажется подходящим сценарием тестирования .. Ты думаешь ?? - person Dimitris Efst; 29.01.2020

У вас есть 2 варианта:

Добавьте обратный вызов к вашим реквизитам, который будет вызываться, когда вызываетсяImageIsMissing:

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 для получения количества вызовов. Поскольку вы используете функциональный компонент, нет возможности получить доступ к этой функции напрямую.

Надеюсь это поможет.

person Kaca992    schedule 30.01.2020