如何为Angular独立组件测试提供Mocked NGRX Store?解决注入报错
解决独立组件测试中
provideMockStore()触发_StoreRootModule缺失的问题 问题根源
你的独立组件导入了FeatureStoreModule,而NgRx的Feature模块依赖根Store模块的初始化上下文。在独立组件的测试环境中,仅通过provideMockStore()提供模拟Store是不够的——Feature模块会强制要求根Store模块已被初始化,否则就会抛出NullInjectorError。
可行解决方案
方案1:在测试配置中先初始化根Store模块
即使使用模拟Store,也需要先通过StoreModule.forRoot({})初始化根Store的基础上下文,再提供模拟Store:
import { TestBed } from '@angular/core/testing'; import { StoreModule } from '@ngrx/store'; import { provideMockStore } from '@ngrx/store/testing'; import { YourStandaloneComponent } from './your-component.component'; import { FeatureStoreModule } from '../feature-store.module'; describe('YourStandaloneComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ imports: [ YourStandaloneComponent, FeatureStoreModule, StoreModule.forRoot({}) // 先初始化根Store模块 ], providers: [ provideMockStore({ initialState: {} }) // 再提供模拟Store实例 ] }).compileComponents(); }); // 测试用例编写... });
方案2:避免导入FeatureStoreModule,直接引用所需符号
如果你的组件只是用到FeatureStore里的选择器、动作,不需要整个模块的其他功能,可以直接导入这些单独的符号,绕开FeatureStoreModule对根Store的依赖:
// 组件文件中修改导入 import { yourFeatureSelector } from './feature.selectors'; import { YourAction } from './feature.actions'; // 测试文件中不再导入FeatureStoreModule await TestBed.configureTestingModule({ imports: [YourStandaloneComponent], providers: [provideMockStore({ initialState: {} })] }).compileComponents();
方案3:手动提供StoreRootModule的模拟依赖
如果前两种方案不适用,可以直接给测试环境提供一个空的StoreRootModule模拟,满足Feature模块的依赖要求:
import { MockStore, provideMockStore } from '@ngrx/store/testing'; import { StoreRootModule } from '@ngrx/store'; beforeEach(async () => { await TestBed.configureTestingModule({ imports: [YourStandaloneComponent, FeatureStoreModule], providers: [ provideMockStore({ initialState: {} }), { provide: StoreRootModule, useValue: {} } // 模拟根Store模块 ] }).compileComponents(); });
额外说明
NgRx 16的Feature模块设计要求必须在根Store模块初始化后才能使用,这个规则在测试环境中同样生效。独立组件的测试配置虽然更轻量化,但涉及NgRx时,必须保证Store的根上下文存在。
内容的提问来源于stack exchange,提问作者Filip Strandberg
相关产品推荐
相关产品推荐

