我有一个反应组件
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,当该变化时,我们滚动到图标列表的开头。
我也遇到了类似的问题。我能够通过添加以下内容来使测试通过并消除错误:
Element.prototype.scrollTo = jest.fn();
通过将其添加到 setupTests 文件 setupTests 文件中,它应该可以消除错误,但由于它现在是一个模拟,因此您将无法测试以太功能。
此外,我喜欢测试库没有准备或配备来测试滚动事件,如果你想测试它们,你需要一个基于浏览器的测试环境,而不是像 jest 和测试库这样的基于节点的测试环境。
希望这有帮助。
编辑1:
但是,您只能测试该函数是否已被调用,例如:
expect(Element.prototype.scrollTo).toHaveBeenCalled();