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

如何Mock在函数外部实例化的OAuth2客户端?

解决Jest Mock Google OAuth2实例化不生效的问题

问题出在模块加载时机:你的oauth2Client是在generateOAuthLink函数外、模块加载阶段就实例化的,若Jest Mock是在导入被测试模块之后才设置,此时真实的OAuth2已经被用来创建实例,Mock自然不会生效。

解决步骤如下:

1. 在导入被测试模块前完成Mock

必须确保apiCallout.js加载前,就把googleapis模块Mock好,这样模块内的oauth2Client会基于Mock的OAuth2构造函数实例化。

示例测试文件代码:

// 先Mock googleapis,再导入被测试模块
jest.mock('googleapis', () => {
  // 模拟OAuth2构造函数,返回带有mock方法的实例
  const mockOAuth2Instance = {
    generateAuthUrl: jest.fn(() => 'https://mock-oauth-authorize-url.com')
  };
  const mockOAuth2 = jest.fn(() => mockOAuth2Instance);

  return {
    google: {
      auth: {
        OAuth2: mockOAuth2
      }
    }
  };
});

// 现在导入被测试模块,此时模块内的oauth2Client会使用Mock的OAuth2
const { generateOAuthLink } = require('./apiCallout');

describe('generateOAuthLink', () => {
  it('返回Mock的授权链接', () => {
    const result = generateOAuthLink();
    expect(result).toBe('https://mock-oauth-authorize-url.com');
    
    // 验证OAuth2构造函数是否被正确调用
    const { OAuth2 } = require('googleapis').google.auth;
    expect(OAuth2).toHaveBeenCalled();
    // 验证generateAuthUrl方法是否被调用
    expect(OAuth2.mock.results[0].value.generateAuthUrl).toHaveBeenCalled();
  });
});

2. 按需重置模块缓存(可选)

如果测试需要多次加载apiCallout.js(比如不同测试用例需要不同Mock逻辑),可在每个测试前重置模块缓存,避免之前的实例残留:

beforeEach(() => {
  jest.resetModules();
});

test('使用不同Mock的场景', () => {
  // 临时Mock googleapis
  jest.mock('googleapis', () => {
    const mockOAuth2 = jest.fn(() => ({
      generateAuthUrl: jest.fn(() => 'https://another-mock-url.com')
    }));
    return { google: { auth: { OAuth2: mockOAuth2 } } };
  });

  const { generateOAuthLink } = require('./apiCallout');
  expect(generateOAuthLink()).toBe('https://another-mock-url.com');
});

核心逻辑就是让Mock优先于被测试模块加载,确保模块初始化时使用的是Mock构造函数,而非真实的Google API实现。

内容的提问来源于stack exchange,提问作者hungry-hippo56

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 13:57:12