推荐使用 tohavebeencalledtimes(n) 验证 spy 调用次数,如 expect(spy).tohavebeencalledtimes(1);也可手动检查 spy.mock.calls.length;需配合 mockclear() 或 mockrestore() 重置状态,避免历史调用干扰。

在 JavaScript Mock 模拟中,验证 spy 函数被调用的具体次数,主要依靠 Jest 提供的 mock.calls.length 或更语义化的断言方法 toHaveBeenCalledTimes(n)。
使用 toHaveBeenCalledTimes() 断言调用次数
这是最推荐、最清晰的方式。Jest 的 mock 函数(包括 jest.fn() 创建的 spy)支持链式断言:
-
expect(spy).toHaveBeenCalledTimes(1)—— 验证恰好被调用 1 次 -
expect(spy).toHaveBeenCalledTimes(0)—— 验证从未被调用(常用于条件分支测试) -
expect(spy).toHaveBeenCalledTimes(3)—— 验证被调用了 3 次
手动检查 mock.calls.length
如果你需要在断言前做逻辑判断,或配合其他条件(比如动态期望值),可以直接读取长度:
console.log(spy.mock.calls.length); // 输出实际调用次数expect(spy.mock.calls.length).toBe(2);- 注意:
spy.mock.calls是一个二维数组,每个子数组代表一次调用的参数列表,因此.length就是调用次数
确保 spy 正确绑定和重置
调用次数统计依赖于 spy 的生命周期管理:
- 测试前用
spy.mockClear()清空历史记录(避免上一个 test 影响当前结果) - 若使用
jest.spyOn(obj, 'method'),记得在afterEach中调用mockRestore()以恢复原方法 - 未清理时,多次运行同一测试可能导致
toHaveBeenCalledTimes(1)失败(实际为 2、3…)
结合调用参数做更精细验证
仅验次数不够?可进一步确认每次调用的输入是否符合预期:
-
expect(spy).toHaveBeenNthCalledWith(1, 'arg1', 2)—— 第 1 次调用参数是'arg1'和2 -
expect(spy.mock.calls[0]).toEqual(['arg1', 2])—— 手动比对第 1 次参数数组 -
expect(spy).toHaveBeenCalledWith('expected')—— 至少有一次以该参数调用过
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











