React Testing Library测试报错:scrollTo不是函数问题求助
修复React组件单元测试中scrollTo方法报错问题
问题场景
React品牌滚动组件在浏览器中运行正常,但执行单元测试时抛出如下错误:
TypeError: _scrollViewRef$curren.scrollTo is not a function
错误指向组件中依赖screenWidth的useEffect钩子,该钩子调用了DOM元素的scrollTo方法并传入对象参数。
错误原因
Testing Library默认使用JSDOM作为测试环境,而JSDOM的scrollTo方法仅支持传统的scrollTo(x, y)参数形式,不兼容组件中使用的scrollTo({ left: ..., behavior: 'smooth' })对象参数写法,导致测试时调用失败。
解决方案
方法1:测试中mock scrollTo方法
在测试用例中直接mock HTMLElement的scrollTo方法,跳过实际执行逻辑:
import React from 'react'; import { render, screen } from '@testing-library/react'; import PopularBrands from './PopularBrands'; describe('PopularBrands', () => { test.only('renders the component', () => { // 模拟scrollTo方法,避免JSDOM不兼容问题 window.HTMLElement.prototype.scrollTo = jest.fn(); 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(); }); });
方法2:组件内兼容scrollTo参数形式
修改组件中的scrollTo调用逻辑,兼容两种参数形式,同时保留浏览器端的平滑滚动效果:
useEffect(() => { const element = scrollViewRef.current; if (!element) return; try { // 优先尝试对象参数形式(支持平滑滚动) element.scrollTo({ left: screenWidth, behavior: 'smooth' }); } catch (error) { // 降级为JSDOM支持的参数形式 element.scrollTo(screenWidth, 0); } }, [screenWidth]);
方法3:全局打补丁
在测试入口文件(如setupTests.js)中添加全局补丁,让JSDOM支持scrollTo的对象参数:
beforeAll(() => { Element.prototype.scrollTo = jest.fn(function(options) { if (typeof options === 'object') { this.scrollLeft = options.left ?? this.scrollLeft; this.scrollTop = options.top ?? this.scrollTop; } else { this.scrollLeft = options; this.scrollTop = arguments[1]; } }); });
内容的提问来源于stack exchange,提问作者NuriLacka
相关产品推荐
相关产品推荐

