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

使用Jest模拟嵌套对象时如何使用简写简化测试代码

Jest 嵌套对象Mock的简洁写法

下面提供3种适用不同场景的简写方案:

方案1:一次性字面量赋值

适合嵌套层级不深的场景,直接按对象结构一次性定义,无需逐层赋值:

describe('test cli-request call', () => {
  it('api injection succeeded', () => {
    window.api = {
      cli: {
        call: jest.fn()
      }
    }
    const mockCmdline = 'whatever';
    CLIRequest(mockCmdline);
    expect(window.api.cli.call).toBeCalledTimes(1);
  });
})

如果外层属性本身也需要是可监听调用的Mock函数,给对应层级加上jest.fn()即可,示例:

// 若window.api、window.api.cli本身也需要作为函数被调用
window.api = Object.assign(jest.fn(), {
  cli: Object.assign(jest.fn(), {
    call: jest.fn()
  })
})

方案2:用内置jest.mocked实现深度Mock(Jest 27.4及以上版本支持)

适合有TS类型定义的场景,自动带类型提示,第二个参数传true即可开启深度Mock:

// 自动将所有嵌套属性转为Mock函数
window.api = jest.mocked({}, { deep: true })
const mockCmdline = 'whatever';
CLIRequest(mockCmdline);
expect(window.api.cli.call).toBeCalledTimes(1);

方案3:自定义通用深度Mock函数

适合嵌套层级很深、不想手动定义每一层结构的场景,用Proxy封装后可无限层级自动生成Mock:

// 提前封装通用工具函数
const createDeepMock = () => new Proxy(jest.fn(), {
  get(target, prop) {
    if (Reflect.has(target, prop)) return Reflect.get(target, prop)
    return target[prop] = createDeepMock()
  }
})

// 业务测试代码仅需一行
window.api = createDeepMock()
const mockCmdline = 'whatever';
CLIRequest(mockCmdline);
expect(window.api.cli.call).toBeCalledTimes(1);

注意:如果业务逻辑中外层属性仅为普通对象、不需要作为函数被调用,不需要给外层加jest.fn(),仅给最终需要校验调用的方法加Mock即可,减少不必要的性能开销。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 18:06:00