Jest中spyOn(console, 'log')未匹配输出?是否存在Bug?
问题原因
当你使用 jest.spyOn(console, 'log') 后,toHaveBeenCalledWith 会严格校验调用时的参数数量和顺序。如果 console.log 被传入多个参数(比如你的复现案例中是三个参数:'haystack', "DhG44n", 'haystack'),但你的断言只提供了一个匹配器,Jest 会认为调用参数不匹配——因为它期望 spy 被调用时恰好只有一个参数符合正则,而实际调用有三个参数。
在你的原始场景中,虽然控制台输出是一行文本,但可能 console.log 被拆成了多个参数调用,或者存在多次调用,导致单一匹配器无法命中目标调用。
解决办法
1. 明确匹配所有参数(忽略无关参数)
如果知道 console.log 的参数数量,用 expect.any() 或 expect.anything() 匹配你不关心的参数,让匹配器数量和实际调用参数数量一致。
复现案例的修复代码:
expect(consoleSpy).toHaveBeenCalledWith( expect.any(String), expect.stringMatching('DhG44n'), expect.any(String) );
原始场景的修复(假设日志是单参数调用):
如果目标日志是作为单个字符串传入 console.log,直接用 expect.stringMatching 即可,Jest 会自动检查是否有任意一次调用匹配:
expect(consoleSpy).toHaveBeenCalledWith( expect.stringMatching(/buying 0.6573442493668066 XBTUSD at 62777/) );
如果日志是多参数调用,调整匹配器数量:
expect(consoleSpy).toHaveBeenCalledWith( expect.any(String), // 匹配第一个无关参数 expect.stringMatching(/buying 0.6573442493668066 XBTUSD at 62777/), // 目标参数 expect.anything() // 匹配剩余所有参数 );
2. 检查任意调用是否包含目标内容(不限制参数数量)
如果你不确定参数数量,或者只想确认是否有任意一次调用的参数中包含目标字符串,可以遍历 spy 的调用记录:
// 获取所有调用记录 const allCalls = consoleSpy.mock.calls; // 检查是否有任意一次调用的任意参数匹配正则 const hasTargetLog = allCalls.some(call => call.some(arg => /buying 0.6573442493668066 XBTUSD at 62777/.test(arg) ) ); expect(hasTargetLog).toBe(true);
这种方式不需要关心参数数量和调用顺序,只要存在符合条件的调用就会通过测试。
内容的提问来源于stack exchange,提问作者Dave Scotese
相关产品推荐
相关产品推荐

