Test useRef onError Fn, с React-Testing-Library и Jest - PullRequest
0 голосов
/ 29 января 2020

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

Эта строка в основном предотвращает бесконечность L oop в случае отсутствия обоих изображений

Проблема: Я хочу проверить, что мой 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, если он вызывался после. Мне действительно нужна помощь в этом ..

Ответы [ 2 ]

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

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

0 голосов
/ 29 января 2020

Вы должны проверить, вызывается ли ваша функция или нет, это называется подробностями тестирования, скорее вы должны проверить, есть ли у вашего элемента img правильные значения sr c.

Даже вам следует добавить некоторые alt и user getByAltText для выбора элемента изображения

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