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

如何在Jest中Mock嵌套类方法:实现TwitterClient.media.mediaUploadStatus模拟

正确Mock写法

写法1:全局Mock(适合所有测试用例都需要Mock该方法的场景)

这种写法在测试文件顶部声明,会Mock整个twitter-api-client包的导出,适合大部分测试场景:

jest.mock('twitter-api-client', () => {
  // 声明mediaUploadStatus的Mock函数,方便后续测试用例修改返回值、断言调用情况
  const mockMediaUploadStatus = jest.fn().mockResolvedValue({
    // 这里填写符合MediaUploadStatus类型的默认返回值,按需调整
    media_id: 'test_media_id',
    processing_info: null
  });

  return {
    TwitterClient: jest.fn().mockImplementation(() => ({
      // 模拟原类的getter属性,和官方实现逻辑保持一致
      get media() {
        return {
          mediaUploadStatus: mockMediaUploadStatus
        };
      }
      // 如果你需要Mock其他getter(比如tweets、accountsAndUsers等),可以在这里补充
    })),
    // 导出Mock函数,供测试用例调用
    mockMediaUploadStatus
  };
});

测试用例中使用方法:

// 导入Mock的方法,TS环境如果报类型错误可以用jest.requireMock替代
const { mockMediaUploadStatus } = jest.requireMock('twitter-api-client');

test('测试mediaUploadStatus调用逻辑', async () => {
  // 单条用例自定义返回值
  mockMediaUploadStatus.mockResolvedValueOnce({
    processing_info: { state: 'pending', check_after_secs: 3 }
  });

  // 执行业务逻辑(包含twitterClient实例化和mediaUploadStatus调用的代码)
  const twitterClient = new TwitterClient({
    apiKey: 'test_key',
    apiSecret: 'test_secret',
    accessToken: 'test_token',
    accessTokenSecret: 'test_token_secret'
  });
  const result = await twitterClient.media.mediaUploadStatus({ media_id: 'test_123' });

  // 断言调用参数和返回值
  expect(mockMediaUploadStatus).toHaveBeenCalledWith({ media_id: 'test_123' });
  expect(result.processing_info.state).toBe('pending');
});

写法2:单测试用例Mock(适合仅部分用例需要Mock的场景)

如果大部分用例不需要Mock该方法,只需要在特定用例中Mock,可以用jest.spyOn手动拦截getter:

import { TwitterClient } from 'twitter-api-client';

test('单用例独立Mock', async () => {
  const mockMediaUploadStatus = jest.fn().mockResolvedValue({});
  // 拦截TwitterClient原型的media getter,返回自定义的Mock对象
  jest.spyOn(TwitterClient.prototype, 'media', 'get').mockReturnValue({
    mediaUploadStatus: mockMediaUploadStatus
  });

  // 执行业务逻辑
  const twitterClient = new TwitterClient({/* 配置参数 */});
  await twitterClient.media.mediaUploadStatus({/* 调用参数 */});

  // 断言逻辑
  expect(mockMediaUploadStatus).toHaveBeenCalled();
});

原写法问题说明

你之前的写法本身基础逻辑是可用的,主要有3处可以优化:

  1. mediaUploadStatus是异步方法,返回值为Promise,原写法返回普通对象虽然await也能自动包装,但用mockResolvedValue更符合原方法的类型定义
  2. 没有暴露Mock的mediaUploadStatus函数,无法在测试用例中修改返回值、断言调用参数和次数
  3. 直接将media定义为普通属性,没有模拟原类的getter实现,极端场景下(比如业务代码判断属性描述符)可能出现逻辑不一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 07:18:01