如何在单元测试中触发NgRx SignalStore的onDestroy钩子?
解决Angular SignalStore onDestroy钩子的单元测试问题
要验证SignalStore的onDestroy钩子是否调用了dependency.stop(),核心是要触发Store实例的销毁生命周期。直接通过TestBed.inject获取的Store属于TestBed根注入器,该注入器会在整个测试套件结束后才销毁,无法在单个测试中手动触发销毁。以下是两种可行的解决方案:
方案1:手动创建独立注入器并销毁
通过Injector.create创建一个独立的注入器,手动管理Store的生命周期,调用注入器的destroy()方法即可触发Store的onDestroy钩子:
import { Injector } from '@angular/core'; it('should stop dependency when destroyed', () => { const fakeDependency = { start: jest.fn(), stop: jest.fn() }; // 创建独立注入器,包含Store和依赖的提供者 const injector = Injector.create({ providers: [ MyStore, { provide: SomeDependency, useValue: fakeDependency } ] }); const store = injector.get(MyStore); // 销毁注入器,触发Store的onDestroy钩子 injector.destroy(); expect(fakeDependency.stop).toHaveBeenCalledOnce(); });
方案2:通过临时组件销毁触发Store销毁
如果你的Store是作为组件级别的提供者使用的,可以创建一个临时组件,将Store注入到组件中,通过销毁组件来触发Store的销毁:
import { Component } from '@angular/core'; import { TestBed } from '@angular/core/testing'; // 定义临时测试组件 @Component({ template: '', providers: [MyStore] }) class TempTestComponent {} it('should stop dependency when destroyed', () => { const fakeDependency = { start: jest.fn(), stop: jest.fn() }; TestBed.configureTestingModule({ declarations: [TempTestComponent], providers: [{ provide: SomeDependency, useValue: fakeDependency }] }); const fixture = TestBed.createComponent(TempTestComponent); // 从组件注入器获取Store实例 const store = fixture.componentRef.injector.get(MyStore); // 销毁组件,连带销毁组件级别的Store实例 fixture.destroy(); expect(fakeDependency.stop).toHaveBeenCalledOnce(); });
原理说明
SignalStore通过withHooks注册的onDestroy钩子,本质是绑定到Store服务的ngOnDestroy生命周期方法。Angular的依赖注入系统中,只有当服务所属的注入器被销毁时,才会调用服务的ngOnDestroy方法,从而触发我们定义的onDestroy逻辑。
内容的提问来源于stack exchange,提问作者Sergio Mazzoleni
相关产品推荐
相关产品推荐

