You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 15:45:05