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

如何用Jest测试unsubscribeFocus与unsubscribeBlur?报错解决

解决Jest测试componentWillUnmount时this.unsubscribeFocus is not a function报错

以下是几种针对性的解决方法,根据你的测试场景选合适的:

  • 直接给组件实例挂载模拟方法
    如果用Enzyme,挂载组件后直接给实例赋值mock函数:

    import { mount } from 'enzyme';
    import YourComponent from './YourComponent';
    
    test('componentWillUnmount calls unsubscribe methods', () => {
      const wrapper = mount(<YourComponent />);
      // 给组件实例添加模拟方法
      wrapper.instance().unsubscribeFocus = jest.fn();
      wrapper.instance().unsubscribeBlur = jest.fn();
      
      wrapper.unmount();
      
      // 验证方法被调用
      expect(wrapper.instance().unsubscribeFocus).toHaveBeenCalled();
      expect(wrapper.instance().unsubscribeBlur).toHaveBeenCalled();
    });
    

    要是用React Testing Library,就先获取组件实例再赋值:

    import { render, unmountComponentAtNode } from '@testing-library/react';
    import YourComponent from './YourComponent';
    import ReactTestUtils from 'react-dom/test-utils';
    
    test('componentWillUnmount calls unsubscribe methods', () => {
      const container = document.createElement('div');
      render(<YourComponent />, { container });
      const instance = ReactTestUtils.getInstance(container.firstChild);
      
      instance.unsubscribeFocus = jest.fn();
      instance.unsubscribeBlur = jest.fn();
      
      unmountComponentAtNode(container);
      
      expect(instance.unsubscribeFocus).toHaveBeenCalled();
    });
    
  • 模拟生成unsubscribe的源头方法
    如果组件里的unsubscribeFocus是通过某个订阅方法(比如this.subscribeFocus())返回的,直接模拟这个订阅方法让它返回mock函数:

    import { mount } from 'enzyme';
    import YourComponent from './YourComponent';
    
    test('componentWillUnmount calls unsubscribe methods', () => {
      // 模拟原型上的订阅方法,返回mock的unsubscribe函数
      const mockUnsubscribe = jest.fn();
      jest.spyOn(YourComponent.prototype, 'subscribeFocus').mockReturnValue(mockUnsubscribe);
      jest.spyOn(YourComponent.prototype, 'subscribeBlur').mockReturnValue(jest.fn());
      
      const wrapper = mount(<YourComponent />);
      // 此时componentDidMount里会把返回的mock赋值给this.unsubscribeFocus
      wrapper.unmount();
      
      expect(mockUnsubscribe).toHaveBeenCalled();
    });
    

    注意测试完要恢复原型方法,避免影响其他测试:

    afterEach(() => {
      jest.restoreAllMocks();
    });
    
  • 处理shallow挂载的情况
    要是用shallow挂载没执行componentDidMount(组件里的unsubscribeFocus是在这个周期赋值的),直接手动给实例加模拟方法就行:

    import { shallow } from 'enzyme';
    import YourComponent from './YourComponent';
    
    test('componentWillUnmount calls unsubscribe methods', () => {
      const wrapper = shallow(<YourComponent />);
      wrapper.instance().unsubscribeFocus = jest.fn();
      wrapper.instance().unsubscribeBlur = jest.fn();
      
      wrapper.unmount();
      
      expect(wrapper.instance().unsubscribeFocus).toHaveBeenCalled();
    });
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 11:15:37