如何在Jest中对多次调用的函数使用toHaveBeenCalledAfter校验调用顺序
你遇到的断言失败是因为toHaveBeenCalledAfter默认会校验spy的所有调用记录,只要存在任意一次调用早于目标spy的调用,就会返回失败,而你setVisible第一次传true的调用确实发生在API请求之前,因此校验不通过。
推荐你把两个校验合并到同一个用例里,用Jest原生的mock.invocationCallOrder属性校验指定调用的时序,这个属性存储了每次调用的全局递增序号,序号越大调用时间越晚,实现代码如下:
import 'jest-extended'; describe('foo', () => { it('should control spinner display order correctly when calling api', async () => { // 初始化mock const setVisibleSpy = jest.spyOn(Spinner, 'setVisible').mockReturnValue(true); const doApiCallSpy = jest.spyOn(ApiService, 'doApiCall').mockResolvedValue(true); // 执行目标函数,注意必须加await等待异步逻辑执行完成 await foo(); // 校验调用参数符合预期,避免参数传反 expect(setVisibleSpy).toHaveBeenNthCalledWith(1, true); expect(doApiCallSpy).toHaveBeenCalledTimes(1); expect(setVisibleSpy).toHaveBeenNthCalledWith(2, false); // 校验顺序:显示Spinner早于API请求 expect(setVisibleSpy.mock.invocationCallOrder[0]) .toBeLessThan(doApiCallSpy.mock.invocationCallOrder[0]); // 校验顺序:API请求早于隐藏Spinner expect(doApiCallSpy.mock.invocationCallOrder[0]) .toBeLessThan(setVisibleSpy.mock.invocationCallOrder[1]); }) })
这份实现逻辑完整,不需要依赖额外匹配器的版本兼容性,同时避免了拆分用例导致的重复创建Spy的冗余代码。
如果你想继续用jest-extended的顺序匹配器,可以使用支持指定调用次数的写法(需保证jest-extended版本≥2.0.0):
// 仅校验第2次setVisible调用发生在doApiCall之后 expect(setVisibleSpy).toHaveBeenCalledAfter(doApiCallSpy, { callCount: 2 });
内容的提问来源于stack exchange,提问作者eXception
相关产品推荐
相关产品推荐

