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

如何在Jest中mock .then()与.catch()?AWS Cognito场景测试问题

报错原因

你遇到的TypeError: cognito.signUp(...).then(...).catch is not a function报错,核心是cognito.signUp()调用后经过.then()返回的不是Promise实例,只有Promise类型才支持链式调用.catch()方法。绝大多数情况是你对signUp的mock不符合实际返回规则:要么signUp没返回Promise,要么你单独mock了.then方法但返回了普通值而非Promise。

解决示例

分两种常见的AWS Cognito调用场景给出mock方案:

场景1:业务代码直接调用signUp().then().catch

如果你的业务代码中signUp本身返回Promise,写法如下:

// 业务代码示例
export const registerUser = (userData) => {
  return cognito.signUp({
    ClientId: process.env.COGNITO_CLIENT_ID,
    Username: userData.phone,
    Password: userData.password
  })
  .then(res => {
    // 你的then块逻辑
    return { success: true, data: res }
  })
  .catch(err => {
    // 你的catch块逻辑
    return { success: false, error: err.message }
  })
}

对应的Jest测试代码:

import { registerUser } from './your-auth-file'
import cognito from './cognito-instance'

// mock cognito实例的signUp方法
jest.mock('./cognito-instance', () => ({
  signUp: jest.fn()
}))

// 测试.then分支逻辑
it('handles signUp success correctly', async () => {
  // mock signUp返回resolve状态的Promise,触发then逻辑
  const mockSuccessRes = { UserSub: 'test-123', UserConfirmed: false }
  cognito.signUp.mockResolvedValueOnce(mockSuccessRes)

  const result = await registerUser({ phone: '13800000000', password: 'Test@1234' })
  expect(result.success).toBe(true)
  expect(result.data).toEqual(mockSuccessRes)
})

// 测试.catch分支逻辑
it('handles signUp error correctly', async () => {
  // mock signUp返回reject状态的Promise,触发catch逻辑
  const mockError = new Error('Username already exists')
  cognito.signUp.mockRejectedValueOnce(mockError)

  const result = await registerUser({ phone: '13800000000', password: 'Test@1234' })
  expect(result.success).toBe(false)
  expect(result.error).toBe('Username already exists')
})

场景2:业务代码使用signUp().promise().then().catch(AWS SDK v2标准写法)

AWS SDK v2中调用服务方法默认返回AWS.Request对象,需要手动调用.promise()才会返回Promise,对应写法如下:

// 业务代码示例
export const registerUser = (userData) => {
  return cognito.signUp({
    ClientId: process.env.COGNITO_CLIENT_ID,
    Username: userData.phone,
    Password: userData.password
  })
  .promise()
  .then(res => {
    return { success: true, data: res }
  })
  .catch(err => {
    return { success: false, error: err.message }
  })
}

对应的Jest测试代码:

import { registerUser } from './your-auth-file'
import cognito from './cognito-instance'

jest.mock('./cognito-instance', () => ({
  signUp: jest.fn()
}))

// 测试.then分支逻辑
it('handles signUp success correctly', async () => {
  const mockSuccessRes = { UserSub: 'test-123', UserConfirmed: false }
  // mock signUp返回带promise方法的对象,promise方法返回resolve状态的Promise
  cognito.signUp.mockReturnValueOnce({
    promise: jest.fn().mockResolvedValueOnce(mockSuccessRes)
  })

  const result = await registerUser({ phone: '13800000000', password: 'Test@1234' })
  expect(result.success).toBe(true)
  expect(result.data).toEqual(mockSuccessRes)
})

// 测试.catch分支逻辑
it('handles signUp error correctly', async () => {
  const mockError = new Error('Password does not meet policy requirements')
  cognito.signUp.mockReturnValueOnce({
    promise: jest.fn().mockRejectedValueOnce(mockError)
  })

  const result = await registerUser({ phone: '13800000000', password: '123' })
  expect(result.success).toBe(false)
  expect(result.error).toBe('Password does not meet policy requirements')
})
注意点

不要单独mocksignUp的.then方法,必须保证signUp的返回值是完整的Promise实例,否则链式调用.catch必然报错。如果你是全局mock AWS SDK,要保证CognitoIdentityServiceProvider实例的调用路径和业务代码完全一致,避免mock失效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 11:30:03