Jest模拟函数未被调用:PubSub组件单元测试问题排查
问题原因及修复方案
核心问题:模块导入与mock顺序错误
你在调用jest.mock之前就已经导入了publishEvent,Jest的模块系统会缓存已加载的模块,导致后续的mock无法替换publish_to_topic的原始实现,所以mockPublishToTopic始终不会被调用。
另外还有两个容易忽略的细节:
publishEvent是异步函数,测试中没有用await等待其执行完成,断言可能在函数调用结束前就执行了。- 测试代码里的
event变量未定义,会导致运行报错。
修复方案
方案一:提前mock模块并重置状态
将jest.mock放在所有导入语句之前,确保模块加载时就使用mock实现,再在beforeEach中重置mock状态:
// 先执行mock,再导入目标模块 jest.mock('./../../src/common/pubsub/publish_to_topic', () => jest.fn()); import { publishEvent } from './../../src/publishers/avoidance_area_change_event'; import mockPublishToTopic from './../../src/common/pubsub/publish_to_topic'; describe("test publisher", () => { beforeEach(() => { // 重置mock的调用记录和实现 mockPublishToTopic.mockReset(); }); it("test1", async () => { const event = {}; // 补充定义event变量 const time = new Date(); const metadata = {}; // await异步函数,确保执行完成后再断言 await publishEvent(event, time, metadata); expect(mockPublishToTopic).toBeCalled(); }); })
方案二:使用jest.spyOn mock默认导出
通过spyOn监听模块的默认导出,动态替换为mock函数:
import { publishEvent } from './../../src/publishers/avoidance_area_change_event'; import * as pubSubModule from './../../src/common/pubsub/publish_to_topic'; describe("test publisher", () => { let mockPublishToTopic; beforeEach(() => { // spyOn默认导出,替换为mock函数 mockPublishToTopic = jest.spyOn(pubSubModule, 'default').mockImplementation(jest.fn()); }); afterEach(() => { // 恢复原始实现,避免影响其他测试 mockPublishToTopic.mockRestore(); }); it("test1", async () => { const event = {}; const time = new Date(); const metadata = {}; await publishEvent(event, time, metadata); expect(mockPublishToTopic).toBeCalled(); }); })
内容的提问来源于stack exchange,提问作者dalastboss
相关产品推荐
相关产品推荐

