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

如何在Enzyme中模拟触发readystatechange事件测试React组件?

模拟document.readystatechange事件测试React组件逻辑

这问题我之前在测试React类组件时也碰到过,确实因为document.readyState是只读属性,直接改它行不通,但有几种实用的方法可以模拟触发事件并验证你的API请求逻辑:

方法1:重写readyState并手动派发事件

我们可以通过Object.defineProperty重写document.readyState的getter,让它返回我们需要的complete状态,然后手动创建并派发readystatechange事件,这样组件里的监听逻辑就会被触发。

举个Jest测试的例子:

import { render } from '@testing-library/react';
import YourComponent from './YourComponent';
import axios from 'axios';

// Mock API请求
jest.mock('axios');

test('发起API请求当document readyState变为complete', () => {
  // 重写document.readyState的getter,返回'complete'
  Object.defineProperty(document, 'readyState', {
    get: () => 'complete',
    configurable: true, // 允许后续重置
  });

  // 挂载组件
  render(<YourComponent />);

  // 手动触发readystatechange事件
  const event = new Event('readystatechange');
  document.dispatchEvent(event);

  // 断言API请求已被调用
  expect(axios.get).toHaveBeenCalled();

  // 重置document.readyState,避免影响其他测试
  Object.defineProperty(document, 'readyState', {
    get: () => 'interactive', // 恢复默认值,根据你的测试环境调整
    configurable: true,
  });
});

方法2:直接获取并执行事件回调

如果你不想手动派发事件,也可以通过监听document.addEventListener来拿到组件绑定的回调函数,然后直接调用它,同时确保回调里的readyState是complete。

示例代码:

import { render } from '@testing-library/react';
import YourComponent from './YourComponent';
import axios from 'axios';

jest.mock('axios');

test('验证readystatechange到complete时的逻辑', () => {
  // 监听document.addEventListener方法
  const addEventListenerSpy = jest.spyOn(document, 'addEventListener');

  // 挂载组件,触发componentDidMount绑定事件
  render(<YourComponent />);

  // 从spy的调用记录中找到readystatechange的回调函数
  const [, callback] = addEventListenerSpy.mock.calls.find(
    ([eventName]) => eventName === 'readystatechange'
  );

  // 临时修改readyState为complete
  Object.defineProperty(document, 'readyState', {
    get: () => 'complete',
    configurable: true,
  });

  // 直接执行回调
  callback();

  // 断言API请求已触发
  expect(axios.get).toHaveBeenCalled();

  // 清理spy和重置readyState
  addEventListenerSpy.mockRestore();
  Object.defineProperty(document, 'readyState', {
    get: () => 'interactive',
    configurable: true,
  });
});

注意事项

  • 记得在测试完成后重置document.readyState和所有mock,避免污染其他测试用例;
  • 如果你的API请求是异步的,需要用async/await配合waitFor(React Testing Library)或者setTimeout来等待断言完成;
  • 不同的测试框架(比如Jest、Mocha)语法略有差异,但核心思路一致:要么模拟状态+派发事件,要么直接调用回调。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:12:12