如何在Jest测试中用toHaveBeenCalledWith配合expect.objectContaining匹配3个对象
实现方案
要实现你的需求,需要先匹配toHaveBeenCalledWith的参数位和你监听函数的实际入参顺序,再结合expect.objectContaining做结构断言,具体实现如下:
核心注意点
toHaveBeenCalledWith的入参要和你监听的函数PubSub.topic的实际入参顺序完全对应,如果你调用PubSub.topic时是先传主题名、再传数据数组,那toHaveBeenCalledWith的第一个参数也要写对应的主题名,第二个才是数组断言- 如果你要求传入的数组正好只有3个符合结构的对象、顺序匹配,不需要加
expect.arrayContaining,直接写数组即可 - 如果你要求传入的数组至少包含3个符合结构的对象,允许有额外元素、顺序不限制,才需要用
expect.arrayContaining包裹
修正后的正确代码
你原代码存在多处语法错误:it后多余的点、括号不配对、数组元素缺逗号,修正后示例如下:
it('reports fix date', async () => { // 模拟依赖返回值 aService.returnValue = [{ activeFrom: '2020-04-19T10:01:58.135Z' }]; // 注册spy监听PubSub.topic方法 const somethingSpy = jest.spyOn(PubSub, 'topic'); // 执行被测试的逻辑 await service.report([ { activeFrom: addDays(new Date(), 30), } ]); // 断言场景1:PubSub.topic被调用时,传入的第一个参数正好是3个符合结构的对象,顺序匹配 expect(somethingSpy).toHaveBeenCalledWith( [ expect.objectContaining({ activeFrom: '2020-04-19T10:01:58.135Z' }), expect.objectContaining({ activeFrom: '2020-04-19T10:01:58.135Z' }), expect.objectContaining({ activeFrom: '2020-04-19T10:01:58.135Z' }) ] ); // 断言场景2:PubSub.topic被调用时,传入的第一个参数至少包含3个符合结构的对象,顺序、额外元素不限制 // expect(somethingSpy).toHaveBeenCalledWith( // expect.arrayContaining([ // expect.objectContaining({ // activeFrom: '2020-04-19T10:01:58.135Z' // }), // expect.objectContaining({ // activeFrom: '2020-04-19T10:01:58.135Z' // }), // expect.objectContaining({ // activeFrom: '2020-04-19T10:01:58.135Z' // }) // ]) // ); });
额外说明
如果需要同时严格校验数组长度,可以补充单独的断言:
// 拿到spy第一次调用的第一个参数 const calledArray = somethingSpy.mock.calls[0][0] expect(calledArray.length).toBe(3)
内容的提问来源于stack exchange,提问作者DEV_K
相关产品推荐
相关产品推荐

