Jest toHaveBeenCalledWith断言含数组对象参数报错如何解决
Jest
toHaveBeenCalledWith 结合 arrayContaining 报错排查 核心结论
你的expect.arrayContaining断言语法本身没有错误,报错是实际入参与预期不匹配导致的,和匹配器写法无关。
报错原因拆解
从diff信息可以定位两个核心问题:
- diff 里展示的
- ArrayContaining [xxx]/+ Array [xxx]是Jest的正常输出格式:减号后是你写的预期匹配规则,加号后是实际拿到的普通数组类型入参,不是匹配器失效。 - 断言失败的根本原因是
payment_type字段的实际入参是空数组[],无论你用expect.arrayContaining(['2'])还是直接写['2']做预期,空数组都不可能匹配包含'2'的要求,自然会持续报错。
你提到去掉arrayContaining后依然报错,也是同一个原因:实际值是空数组,和你写的['2']预期完全不符。
解决方法
按照优先级排查处理:
- 先排查测试用例的执行逻辑:确认触发
mockOnChange调用前,是否正确模拟了payment_type选中值为'2'的操作。如果是组件异步更新场景,需要把断言放在waitFor回调内等待状态更新完成,避免在初始化状态(payment_type为空)就提前执行断言。 - 排查是否存在多次调用干扰:如果
mockOnChange在初始化时就会被触发一次(此时payment_type为空),后续选值后才会触发第二次带正确参数的调用,不要直接用toHaveBeenCalledWith,改用lastCalledWith断言最后一次调用的入参,或者打印mockOnChange.mock.calls确认所有调用的入参内容,定位不符合预期的调用时机。 - 如果业务逻辑本身就允许
payment_type为空数组,修改你的断言预期即可,不要强制要求该字段必须包含'2'。
参考正确写法示例
// 模拟用户操作,确保选中对应筛选值 fireEvent.click(screen.getByText('支付方式2')); // 异步场景等待状态更新完成再断言 await waitFor(() => { expect(mockOnChange).lastCalledWith({ order_type: expect.arrayContaining(['1']), number: '', ouser_ids: expect.arrayContaining(['user_id1']), payment_type: expect.arrayContaining(['2']), start_date: old_Date, end_date: current_date, state: 'all', }); });
内容的提问来源于stack exchange,提问作者Prashanth
相关产品推荐
相关产品推荐

