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

使用Middy时单元测试Handler调用,Mock后中间件仍执行如何解决

错误原因

  1. 你在jest.mock的工厂函数中调用了jest.requireActual加载原模块,此时原模块内middy(handler).use(ssm())的初始化逻辑会直接执行,SSM中间件已经挂载到原函数实例上。虽然你后续尝试将导出的makeThirdPartyServiceRequest替换为Jest模拟函数,但如果对象引用替换不彻底,测试时仍然会调用到挂载了中间件的原Middy实例。
  2. 保留原模块所有导出再覆盖单个属性的写法,在部分模块导入场景下可能出现引用残留,导致模拟函数未生效。

解决方案

方案1:直接模拟目标函数(推荐)

不需要加载原模块逻辑,直接导出模拟函数即可,修改mock代码如下:

jest.mock('../src/thirdPartyService', () => ({
  __esModule: true,
  default: {
    // 如果需要保留原模块的其他导出可以保留下面这行,否则建议删除,避免触发原模块初始化逻辑
    // ...(jest.requireActual('../src/thirdPartyService') as { default: {} }).default,
    makeThirdPartyServiceRequest: jest.fn()
  }
}))

// import 语句必须放在 jest.mock 之后(Jest会自动提升jest.mock调用到所有导入前,手动按顺序写更易维护)
import thirdPartyService from '../src/thirdPartyService'
import { mocked } from 'jest-mock'

如果修改后还是触发中间件,可以加一行日志验证模拟是否生效:

it('should makeThirdPartyServiceRequest', async () => {
  // 输出如果是 [Function: mockConstructor] 说明模拟生效,如果是Middy实例说明模拟未生效
  console.log(thirdPartyService.makeThirdPartyServiceRequest)
  // 剩余测试逻辑
})

如果模拟未生效,检查两点:

  • mock中的文件相对路径是否和测试文件到目标模块的路径完全一致,不要写错路径
  • 原模块的导出方式是否和mock匹配:如果原模块是export const makeThirdPartyServiceRequest = xxx命名导出,mock结构不要放在default属性下

方案2:模拟SSM中间件(适用于测试原函数业务逻辑的场景)

如果你不需要mock整个请求函数,只是想跳过SSM中间件的执行,可以直接mock SSM中间件:

jest.mock('@middy/ssm', () => jest.fn(() => ({
  before: jest.fn((handler, next) => next()) // 直接跳过SSM参数拉取逻辑,进入业务代码
})))

注:测试代码中的多余注释// })是笔误,删除即可,不影响逻辑运行。

内容的提问来源于stack exchange,提问作者Muhammad Ali Nazar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 12:54:03