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

React:如何测试组件更新Props时方法是否被调用?

如何测试React组件更新Props时方法是否被调用?

我来帮你解决这个测试问题!你遇到的错误是因为Jest的toBeCalled()断言只兼容自身的mock函数,不识别Sinon的spy对象,所以才会抛出那个错误。下面给你两种可行的解决方案:

方案一:改用Jest原生Mock函数(推荐)

Jest自带强大的mock功能,完全可以替代Sinon实现方法调用的断言,不需要额外依赖第三方库。具体代码如下:

import React from 'react';
import Enzyme, { mount } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import 'jest-styled-components';
import VideoPlayer from './../src/app/components/VideoPlayer/VideoPlayer';

Enzyme.configure({ adapter: new Adapter() });

test('Checks if togglePlayPause gets called when isPaused prop updates', () => {
  // 用Jest spyOn监听组件原型上的togglePlayPause方法
  const toggleSpy = jest.spyOn(VideoPlayer.prototype, 'togglePlayPause');
  
  // 挂载初始props的组件
  const component = mount(
    <VideoPlayer 
      videoURL="http://localhost:3001/vid/local-video.mp4" 
      volume={100} 
      isPaused={false} 
    />
  );
  
  // 更新isPaused props,触发生命周期方法
  component.setProps({ isPaused: true });
  
  // 断言方法被调用,还可以指定调用参数
  expect(toggleSpy).toHaveBeenCalled();
  expect(toggleSpy).toHaveBeenCalledWith(true);
  
  // 清理mock,避免影响其他测试用例
  toggleSpy.mockRestore();
});

方案二:继续使用Sinon,但改用Sinon的断言方法

如果你坚持使用Sinon,只需要把Jest的断言换成Sinon自己的断言函数即可,不要混用两者的断言体系:

import React from 'react';
import Enzyme, { mount } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import 'jest-styled-components';
import sinon from 'sinon';
import VideoPlayer from './../src/app/components/VideoPlayer/VideoPlayer';

Enzyme.configure({ adapter: new Adapter() });

test('Checks if togglePlayPause gets called with Sinon', () => {
  const toggleSpy = sinon.spy(VideoPlayer.prototype, 'togglePlayPause');
  
  const component = mount(
    <VideoPlayer 
      videoURL="http://localhost:3001/vid/local-video.mp4" 
      volume={100} 
      isPaused={false} 
    />
  );
  
  component.setProps({ isPaused: true });
  
  // 使用Sinon的断言方法
  sinon.assert.called(toggleSpy);
  // 断言调用时的参数
  sinon.assert.calledWith(toggleSpy, true);
  
  // 恢复原方法,避免污染组件原型
  toggleSpy.restore();
});

额外优化提示

另外注意,你代码中使用的componentWillReceiveProps是React已经废弃的生命周期方法(React 16.3+),推荐换成componentDidUpdate来处理props更新后的逻辑,写法更符合现代React规范,测试逻辑基本不变:

componentDidUpdate(prevProps) {
  if (prevProps.isPaused !== this.props.isPaused) {
    this.togglePlayPause(this.props.isPaused);
  }
}

内容的提问来源于stack exchange,提问作者DavidWorldpeace

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:59:00