使用ng-mocks的autoSpy时,如何重置Jasmine spy调用?
解决ng-mocks自动spy调用记录重置问题
问题原因
你在主beforeEach中创建的myService实例会被所有后续describe块共享,ngMocks.reset()仅重置ng-mocks的全局配置和注册的mock,不会自动清除已有spy的调用记录,导致第二个测试读取到之前的调用痕迹。
解决方案
方案1:每个测试块创建全新Mock实例(推荐)
将mock实例的创建移到每个describe的beforeEach中,确保每个测试块使用独立的mock实例,自然不会残留调用记录:
let myService: MyService; describe(`点击按钮A时`, () => { beforeEach(() => { // 每个测试块重新生成mock实例 myService = MockService(MyService); // 按钮点击代码 }); it(`应调用functionA一次`, () => { expect(myService.functionA).toHaveBeenCalled(); }); }); describe(`点击按钮B时`, () => { beforeEach(() => { myService = MockService(MyService); // 按钮点击代码 }); it(`不应调用functionA`, () => { expect(myService.functionA).not.toHaveBeenCalled(); }); });
方案2:批量重置已有spy的调用记录
如果需要复用同一个mock实例,可通过遍历mock对象的方法,批量重置每个spy的调用记录:
describe(`点击按钮B时`, () => { beforeEach(() => { // 遍历mock实例的所有方法,重置spy调用记录 Object.keys(myService).forEach(key => { const spy = ngMocks.getSpy(myService, key); if (spy?.calls) { spy.calls.reset(); } }); // 按钮点击代码 }); it(`不应调用functionA`, () => { expect(myService.functionA).not.toHaveBeenCalled(); }); });
补充:解决单个spy重置的类型报错
如果单独重置某个spy时遇到TypeScript类型报错,可通过类型断言明确指定为jasmine Spy:
(myService.functionA as jasmine.Spy).calls.reset();
内容的提问来源于stack exchange,提问作者LocustHorde
相关产品推荐
相关产品推荐

