React 测试库错误:未捕获 [TypeError: _scrollViewRef$curren.scrollTo 不是函数]

问题描述 投票:0回答:1

我有一个反应组件

import React, { useEffect, useRef, useState } from 'react';
import './PopularBrands.scss';
import LG from '../../../assets/images/brands/LG.png';
import Google from '../../../assets/images/brands/Google.jpeg';
import Apple from '../../../assets/images/brands/Apple.png';
import Boch from '../../../assets/images/brands/Boch.png';
import Dyson from '../../../assets/images/brands/Dyson.png';
import Philips from '../../../assets/images/brands/Philips.png';
import Samsung from '../../../assets/images/brands/Samsung.png';
import Simens from '../../../assets/images/brands/Simens.png';
import Sony from '../../../assets/images/brands/Sony.png';
import Xiomi from '../../../assets/images/brands/Xiomi.png';
import { FaChevronLeft } from 'react-icons/fa';
import { FaChevronRight } from 'react-icons/fa';

const PopularBrands = () => {
  const scrollViewRef = useRef<HTMLDivElement | null>(null);
  const [screenWidth, setScreenWidth] = useState(0);
  const [width, setWidth] = useState(0);
  const [widthTotal, setWidthTotal] = useState(0);
  const [showArrow, setShowArrow] = useState(false);

  useEffect(() => {
    function handleWindowResize() {
      if (scrollViewRef.current) setWidth(scrollViewRef.current.clientWidth);
      if (scrollViewRef.current) setWidthTotal(scrollViewRef.current.scrollWidth);
    }

    handleWindowResize();

    window.addEventListener('resize', handleWindowResize);

    return () => {
      window.removeEventListener('resize', handleWindowResize);
    };
  }, []);

  useEffect(() => {
    scrollViewRef.current?.scrollTo({ left: screenWidth, behavior: 'smooth' });
  }, [screenWidth]);

  const toNextPage = () => {
    if (scrollViewRef && screenWidth <= widthTotal) {
      setScreenWidth(screenWidth + width);
    }
  };

  const toPreviosPage = () => {
    if (scrollViewRef && screenWidth >= 0) {
      setScreenWidth(screenWidth - width);
    }
  };

  return (
    <div
      className="brandsContainer"
      onMouseEnter={() => setShowArrow(true)}
      onMouseLeave={() => setShowArrow(false)}>
      <div className="brands" ref={scrollViewRef}>
        <div>
          <img src={LG} alt="lg" />
        </div>
        <div>
          <img src={Google} alt="Google" />
        </div>
        <div>
          <img src={Apple} alt="Apple" />
        </div>
        <div>
          <img src={Boch} alt="Boch" />
        </div>
        <div>
          <img src={Dyson} alt="Dyson" />
        </div>
        <div>
          <img src={Philips} alt="Philips" />
        </div>
        <div>
          <img src={Samsung} alt="Samsung" />
        </div>
        <div>
          <img src={Simens} alt="Simens" />
        </div>
        <div>
          <img src={Sony} alt="Sony" />
        </div>
        <div>
          <img src={Xiomi} alt="Xiomi" />
        </div>
      </div>
      {screenWidth > 0 && showArrow && (
        <div className="scrollIcon scrollBack" onClick={toPreviosPage}>
          <FaChevronLeft fontSize={30} />
        </div>
      )}

      {screenWidth + width < widthTotal && showArrow && (
        <div className="scrollIcon scrollNext" onClick={toNextPage}>
          <FaChevronRight fontSize={30} />
        </div>
      )}
    </div>
  );
};

export default PopularBrands;

它在 UI 中工作正常。但是当我编写以下单元测试时:

import React from 'react';
import { render, screen } from '@testing-library/react';
import PopularBrands from './PopularBrands';

describe('PopularBrands', () => {
  test.only('renders the component', () => {
    render(<PopularBrands />);

    expect(screen.getByAltText('lg')).toBeInTheDocument();
    expect(screen.getByAltText('Google')).toBeInTheDocument();
    expect(screen.getByAltText('Apple')).toBeInTheDocument();
    expect(screen.getByAltText('Boch')).toBeInTheDocument();
    expect(screen.getByAltText('Dyson')).toBeInTheDocument();
    expect(screen.getByAltText('Philips')).toBeInTheDocument();
    expect(screen.getByAltText('Samsung')).toBeInTheDocument();
    expect(screen.getByAltText('Simens')).toBeInTheDocument();
    expect(screen.getByAltText('Sony')).toBeInTheDocument();
    expect(screen.getByAltText('Xiomi')).toBeInTheDocument();
  });
});

测试未通过,我收到错误日志:

  ● PopularBrands › renders the component

    TypeError: _scrollViewRef$curren.scrollTo is not a function

      37 |
      38 |   useEffect(() => {
    > 39 |     scrollViewRef.current?.scrollTo({ left: screenWidth, behavior: 'smooth' });
         |                            ^
      40 |   }, [screenWidth]);
      41 |
      42 |   const toNextPage = () => {

      at src/components/Directory/PopularBrands/PopularBrands.tsx:39:28

我正在尝试寻求帮助来修复我的单元测试。在 useEffect 函数上有一个依赖 screenWidth,当该变化时,我们滚动到图标列表的开头。

reactjs jestjs react-testing-library
1个回答
2
投票

我也遇到了类似的问题。我能够通过添加以下内容来使测试通过并消除错误:

Element.prototype.scrollTo = jest.fn();

通过将其添加到 setupTests 文件 setupTests 文件中,它应该可以消除错误,但由于它现在是一个模拟,因此您将无法测试以太功能。

此外,我喜欢测试库没有准备或配备来测试滚动事件,如果你想测试它们,你需要一个基于浏览器的测试环境,而不是像 jest 和测试库这样的基于节点的测试环境。

希望这有帮助。

编辑1:

但是,您只能测试该函数是否已被调用,例如:

expect(Element.prototype.scrollTo).toHaveBeenCalled();
© www.soinside.com 2019 - 2024. All rights reserved.