测试自定义匹配器中的嵌套对象

问题描述

我想测试一下,是否使用特定的嵌套对象调用函数

myFunction({ variables: { input: { id: 12345,foo: 'bar' }}})

这是我在测试中的 expect

expect(myFunction).toHaveBeenCalledWith(
  expect.objectContaining({
    variables: expect.objectContaining({
      input: expect.objectContaining({
        id: 12345,foo: 'bar'
      })
    })
  })
)

我喜欢这个,因为测试失败时的错误信息非常有用。

由于我必须多次测试对象,因此我想将 toHaveBeenCalledWith 提取到自己的函数中,甚至更好地构建自定义匹配器。

只是将可重复的部分放到自己的函数中是不正确的:

export const parameterFunctionCall = (param: object,name: string = "input"): void => {
  expect.objectContaining({
    variables: expect.objectContaining({
      [name]: expect.objectContaining(param)
    })
  })
}

expect(myFunction).toHaveBeenCalledWith(
  parameterFunctionCall({
    id: 12345,foo: 'bar'
  })
)

解决方法

我认为问题在于 parameterFunctionCall 的返回值。 void 不符合 toHaveBeenCalledWith 的签名:

function (
    this: MatcherState,received: any,...expected: Array<unknown>
): SyncExpectationResult { ... }

在您的情况下,这意味着您应该返回一个 ObjectContaining 实例而不是 void,就像这样:

export const parameterFunctionCall = (param: object,name: string = "input") => {
  return expect.objectContaining({
    variables: expect.objectContaining({
      [name]: expect.objectContaining(param)
    })
  })
}

想想看,如果你没有从parameterFunctionCall返回任何东西,toHaveBeenCalledWith怎么知道要匹配什么? 此外,我在您所写的内容中没有发现任何其他问题(但我绝对不是 TS 专家)。

,

为什么这对您不起作用?你错过了这个功能吗?

expect(data).toHaveProperty(['variables','input','foo'],'bar');
expect(data).toHaveProperty(['variables','id'],12345);
test('test',() => {
    let data = { variables: { input: {id: 12345,foo: 'bar' }}}

    expect(data).toHaveProperty(['variables',12345)
    expect(data).toHaveProperty(['variables','bar')

    let f = jest.fn(() => true)
    f(data)

    expect(f).toHaveBeenCalledWith(data)
})

如果你不想使用这个函数,我为你做了一个递归函数。

let data = { variables: { input: {id: 12345,foo: 'bar' }}}

const nestedCheckerRecursive = (data,arr,iteration) => {
    if (arr.length == iteration) return

    expect(data[arr[iteration].propName])[arr[iteration].method](arr[iteration].data)

    nestedCheckerRecursive(data[arr[iteration].propName],iteration + 1)
}

test('test',() => {
    nestedCheckerRecursive(data,[
        {
            propName: "variables",method: "toBeDefined"
        },{
            propName: "input",{
            propName: "id",method: "toEqual",data: 12345
        }
    ],0)
});

也许我误解了你的问题。身份证