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

如何封装自定义匹配器校验函数是否传入指定嵌套对象参数?

问题原因

你写的parameterFunctionCall存在两个问题:一是没有返回构造好的嵌套匹配器对象,二是显式声明了返回值为void,导致传入toHaveBeenCalledWith的实际值为undefined,无法完成校验。

方案一:轻量工具函数实现(推荐)

不需要修改测试框架配置,直接复用原生expect.objectContaining的能力,同时保留原生清晰的报错提示,实现成本最低:

export const matchNestedVariableInput = (expectedParam: object, inputKey: string = "input") => {
  return expect.objectContaining({
    variables: expect.objectContaining({
      [inputKey]: expect.objectContaining(expectedParam)
    })
  })
}

// 调用方式和你预期的完全一致
expect(myFunction).toHaveBeenCalledWith(
  matchNestedVariableInput({
    id: 12345,
    foo: 'bar'
  })
)
方案二:自定义匹配器实现

如果希望进一步简化调用语法,可以给Jest/Vitest注册自定义匹配器:

  1. 首先在测试全局setup文件中注册匹配器:
// Jest/Vitest 通用实现
expect.extend({
  toHaveBeenCalledWithNestedInput(received: jest.Mock, expectedInput: object, inputKey: string = "input") {
    const expectedMatcher = expect.objectContaining({
      variables: expect.objectContaining({
        [inputKey]: expect.objectContaining(expectedInput)
      })
    })
    const pass = received.mock.calls.some(call => this.equals(call[0], expectedMatcher))

    if (pass) {
      return {
        message: () => `预期函数未被传入包含指定${inputKey}参数的嵌套对象,但实际匹配成功`,
        pass: true
      }
    } else {
      return {
        message: () => `预期函数被传入包含指定${inputKey}参数的嵌套对象,实际所有调用参数为:\n${this.utils.printReceived(received.mock.calls)}`,
        pass: false
      }
    }
  }
})

// TypeScript 项目需要补充类型声明,让IDE识别自定义匹配器
declare module 'expect' {
  interface Matchers<R> {
    toHaveBeenCalledWithNestedInput(expectedInput: object, inputKey?: string): R
  }
}
  1. 测试中直接调用:
expect(myFunction).toHaveBeenCalledWithNestedInput({
  id: 12345,
  foo: 'bar'
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 13:15:00