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

如何正确Mock AWS SDK的Cognito Identity Provider服务?

解决Jest Mock AWS CognitoIdentityServiceProvider验证失败问题

问题分析

你遇到的验证失败主要有三个原因:

  1. 名称拼写错误:Mock的是CognitoIdentityServiceProvider,但验证时写的是CognitoIdentityProviderService(多了一个Service后缀),导致访问prototype.adminGetUser返回undefined。
  2. Mock对象结构错误:你当前的Mock是让构造函数返回实例方法,而非挂载到原型链上,所以直接访问prototype上的方法会找不到。
  3. 实例引用不一致:测试文件中创建的mockCognitoIdentityProviderService实例,和被测试模块内部初始化的实例不是同一个,导致spy无法捕获实际调用。

正确解决方案

方案一:预定义可追踪的Mock方法

将需要Mock的方法提前定义为独立的jest mock函数,确保所有实例共享同一个引用,直接验证这些预定义的mock即可。

// 预定义所有需要Mock的方法
const mockAdminGetUser = jest.fn().mockReturnThis();
const mockGetUser = jest.fn().mockReturnThis();
const mockAdminDeleteUser = jest.fn().mockReturnThis();
const mockAdminUpdateUserAttributes = jest.fn().mockReturnThis();
const mockAssociateSoftwareToken = jest.fn().mockReturnThis();
const mockAdminSetUserMFAPreference = jest.fn().mockReturnThis();
const mockVerifySoftwareToken = jest.fn().mockReturnThis();
const mockAdminCreateUser = jest.fn().mockReturnThis();
const mockAdminUserGlobalSignOut = jest.fn().mockReturnThis();
const mockPromise = jest.fn().mockResolvedValue(true);

// Mock aws-sdk
jest.mock('aws-sdk', () => ({
  ...jest.requireActual('aws-sdk'),
  // 构造函数返回包含预定义mock方法的对象
  CognitoIdentityServiceProvider: jest.fn(() => ({
    adminGetUser: mockAdminGetUser,
    getUser: mockGetUser,
    adminDeleteUser: mockAdminDeleteUser,
    adminUpdateUserAttributes: mockAdminUpdateUserAttributes,
    associateSoftwareToken: mockAssociateSoftwareToken,
    adminSetUserMFAPreference: mockAdminSetUserMFAPreference,
    verifySoftwareToken: mockVerifySoftwareToken,
    adminCreateUser: mockAdminCreateUser,
    adminUserGlobalSignOut: mockAdminUserGlobalSignOut,
    promise: mockPromise,
  })),
}));

// 先导入AWS,再导入被测试模块
import AWS from 'aws-sdk';
import yourServiceModule from './your-service-module';

// 测试用例
test('adminGetUser方法被正确调用', async () => {
  // 调用被测试模块中的业务方法
  await yourServiceModule.fetchUserInfo('user-pool-id', 'test-username');

  // 直接验证预定义的mock函数
  expect(mockAdminGetUser).toHaveBeenCalledWith({
    UserPoolId: 'user-pool-id',
    Username: 'test-username'
  });

  // 验证promise方法被调用
  expect(mockPromise).toHaveBeenCalled();
});

方案二:捕获构造函数返回的实例Mock

如果被测试模块是在模块级别初始化Cognito实例(而非方法内部),可以通过构造函数的mock结果获取实例引用,进而验证方法调用。

jest.mock('aws-sdk', () => {
  // 定义实例Mock
  const cognitoMockInstance = {
    adminGetUser: jest.fn().mockReturnThis(),
    getUser: jest.fn().mockReturnThis(),
    adminDeleteUser: jest.fn().mockReturnThis(),
    adminUpdateUserAttributes: jest.fn().mockReturnThis(),
    associateSoftwareToken: jest.fn().mockReturnThis(),
    adminSetUserMFAPreference: jest.fn().mockReturnThis(),
    verifySoftwareToken: jest.fn().mockReturnThis(),
    adminCreateUser: jest.fn().mockReturnThis(),
    adminUserGlobalSignOut: jest.fn().mockReturnThis(),
    promise: jest.fn().mockResolvedValue(true),
  };

  return {
    ...jest.requireActual('aws-sdk'),
    CognitoIdentityServiceProvider: jest.fn(() => cognitoMockInstance),
  };
});

import AWS from 'aws-sdk';
import yourServiceModule from './your-service-module';

test('验证adminGetUser调用', async () => {
  await yourServiceModule.someBusinessMethod();

  // 获取构造函数返回的实例Mock
  const cognitoInstance = AWS.CognitoIdentityServiceProvider.mock.results[0].value;
  expect(cognitoInstance.adminGetUser).toHaveBeenCalledWith(/* 预期参数 */);
});

关于aws-sdk-mock的正确用法

如果要使用aws-sdk-mock,需确保在导入被测试模块之前完成Mock配置,因为模块级别的实例会在导入时初始化:

import AWSMock from 'aws-sdk-mock';
import AWS from 'aws-sdk';

// 在导入被测试模块前Mock方法
AWSMock.mock('CognitoIdentityServiceProvider', 'adminGetUser', (params, callback) => {
  callback(null, { Username: 'test-user', UserAttributes: [] });
});

// 导入被测试模块
import yourServiceModule from './your-service-module';

test('验证adminGetUser参数', async () => {
  await yourServiceModule.fetchUserInfo('pool-id', 'test-user');

  // 获取调用记录
  const [callParams] = AWSMock.calls('CognitoIdentityServiceProvider', 'adminGetUser')[0];
  expect(callParams).toEqual({
    UserPoolId: 'pool-id',
    Username: 'test-user'
  });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 11:48:25