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

如何使用Jasmine编写Angular中AWS Cognito authenticateUser的测试用例?

没问题,我来帮你搞定Angular组件里Cognito认证的Jasmine测试用例!咱们一步步拆解,从准备工作到核心测试场景都给你安排明白:

一、测试前的准备工作

首先要做的是mock AWS Cognito的所有依赖类,绝对不能让测试调用真实的Cognito服务(否则测试会不稳定、依赖网络,还可能产生无效请求)。我们用Jasmine的spyOn和createSpyObj来模拟这些对象:

// 先声明全局的AWSCognito模拟对象(避免TS报错)
declare const AWSCognito: any;

describe('YourAuthComponent', () => {
  let component: YourAuthComponent;
  let fixture: ComponentFixture<YourAuthComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [YourAuthComponent]
      // 这里如果组件有其他依赖(比如Router、Toast服务),也要一并mock
    }).compileComponents();
  });

  beforeEach(() => {
    // 重置所有mock,避免测试用例之间互相影响
    jasmine.clearAllSpies();

    // 1. 模拟CognitoUserPool构造函数,返回一个空的spy对象
    const mockUserPool = jasmine.createSpyObj('CognitoUserPool', ['']);
    spyOn(AWSCognito, 'CognitoUserPool').and.returnValue(mockUserPool);

    // 2. 模拟AuthenticationDetails构造函数
    spyOn(AWSCognito, 'AuthenticationDetails');

    // 3. 模拟CognitoUser构造函数,重点给authenticateUser方法做spy
    const mockCognitoUser = jasmine.createSpyObj('CognitoUser', ['authenticateUser']);
    spyOn(AWSCognito, 'CognitoUser').and.returnValue(mockCognitoUser);

    // 初始化组件
    fixture = TestBed.createComponent(YourAuthComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });
});
二、核心测试用例编写

1. 测试认证对象的初始化逻辑

验证组件是否正确创建了Cognito的各类实例,并且传入了正确的参数:

it('should initialize Cognito objects with correct pool data and user credentials', () => {
  // 给组件设置测试用的用户名和密码
  component.username = 'test-user-001';
  component.password = 'test-pass-123';
  
  // 假设触发认证的方法叫login(),调用它
  component.login();

  // 验证UserPool是否用预设的poolData创建
  expect(AWSCognito.CognitoUserPool).toHaveBeenCalledWith({
    UserPoolId: '<UserPoolId>',
    ClientId: '<ClientId>'
  });

  // 验证AuthenticationDetails是否传入了正确的用户名密码
  expect(AWSCognito.AuthenticationDetails).toHaveBeenCalledWith({
    Username: 'test-user-001',
    Password: 'test-pass-123'
  });

  // 验证CognitoUser是否用正确的用户名和UserPool实例创建
  expect(AWSCognito.CognitoUser).toHaveBeenCalledWith({
    Username: 'test-user-001',
    Pool: AWSCognito.CognitoUserPool.calls.mostRecent().returnValue
  });
});

2. 测试认证成功的场景

验证当authenticateUser的onSuccess回调触发时,组件的后续行为是否符合预期(比如跳转页面、保存token、更新用户状态等):

it('should handle authentication success correctly', () => {
  // 获取mock的CognitoUser实例
  const mockCognitoUser = AWSCognito.CognitoUser.calls.mostRecent().returnValue;
  
  // 假设组件成功后会调用navigateToHome方法,先给它做spy
  spyOn(component, 'navigateToHome');

  // 触发登录逻辑
  component.username = 'test-user-001';
  component.password = 'test-pass-123';
  component.login();

  // 获取authenticateUser调用时传入的回调对象
  const authCallbacks = mockCognitoUser.authenticateUser.calls.mostRecent().args[1];
  
  // 手动触发onSuccess回调,传入模拟的认证结果
  const mockAuthResult = { 
    idToken: { getJwtToken: () => 'mock-jwt-token-123' } 
  };
  authCallbacks.onSuccess(mockAuthResult);

  // 验证组件是否执行了成功后的逻辑
  expect(component.navigateToHome).toHaveBeenCalled();
  // 如果组件会保存token,也可以验证:
  // expect(component.userToken).toBe('mock-jwt-token-123');
});

3. 测试认证失败的场景

验证当认证失败时,组件是否正确处理错误(比如显示错误提示、重置表单等):

it('should handle authentication failure correctly', () => {
  const mockCognitoUser = AWSCognito.CognitoUser.calls.mostRecent().returnValue;
  
  // 假设组件会调用showErrorAlert显示错误,给它做spy
  spyOn(component, 'showErrorAlert');

  // 触发登录逻辑(用错误的凭证)
  component.username = 'wrong-user';
  component.password = 'wrong-pass';
  component.login();

  // 获取回调对象,手动触发onFailure
  const authCallbacks = mockCognitoUser.authenticateUser.calls.mostRecent().args[1];
  const mockError = new Error('Invalid username or password');
  authCallbacks.onFailure(mockError);

  // 验证错误提示是否被正确调用
  expect(component.showErrorAlert).toHaveBeenCalledWith('Invalid username or password');
});

4. 测试特殊回调场景(可选)

如果你的用户池开启了首次登录强制改密码,还可以测试newPasswordRequired回调:

it('should handle new password required scenario', () => {
  const mockCognitoUser = AWSCognito.CognitoUser.calls.mostRecent().returnValue;
  
  // 假设组件会打开改密码弹窗,给它做spy
  spyOn(component, 'openNewPasswordModal');

  component.login();

  // 获取回调对象,手动触发newPasswordRequired
  const authCallbacks = mockCognitoUser.authenticateUser.calls.mostRecent().args[1];
  const mockUserAttributes = { email: 'test@example.com' };
  const mockRequiredAttributes = ['email_verified'];
  authCallbacks.newPasswordRequired(mockUserAttributes, mockRequiredAttributes);

  // 验证弹窗是否被正确打开
  expect(component.openNewPasswordModal).toHaveBeenCalledWith(mockUserAttributes, mockRequiredAttributes);
});
三、几个关键注意事项
  • 绝对不要调用真实服务:所有Cognito相关的类和方法都要mock,保证测试的独立性和稳定性。
  • 覆盖所有分支:除了成功/失败,还要考虑特殊回调(比如newPasswordRequired、mfaRequired)的场景。
  • 依赖注入的配置:如果你的组件是从environment或注入的配置服务里拿UserPoolId/ClientId,记得在TestBed里提供模拟的配置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:19:22