如何封装自定义匹配器校验函数是否传入指定嵌套对象参数?
问题原因
你写的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注册自定义匹配器:
- 首先在测试全局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 } }
- 测试中直接调用:
expect(myFunction).toHaveBeenCalledWithNestedInput({ id: 12345, foo: 'bar' })
内容的提问来源于stack exchange,提问作者user3142695
相关产品推荐
相关产品推荐

