Angular 16单元测试:如何获取组件的appRuleList与appRuleOptions值
Angular 16单元测试:无法获取组件appRuleList和appRuleOptions值的解决方案
问题根源分析
你的测试用例之所以拿不到目标值,核心问题集中在以下几点:
- 数据结构不匹配:组件订阅store期望接收的是
IApplicationRule类型(包含applicationRule属性的对象),但测试中直接返回了数组,导致组件内的if (userIdentificationPart && userIdentificationPart.applicationRule)判断不成立,两个数组未被赋值。 - Store模拟方式错误:直接spy
_store$.pipe的写法没有正确处理select(applicationRows)操作符,导致数据流不符合组件预期。 - 断言期望值错误:
appRuleOptions的期望值和组件逻辑(selectedName + '/' + x.name)不匹配,应该是['test/ui']而非['power/testing']。 - 未处理
destroySubject:组件用takeUntil(this.destroy)管理订阅生命周期,测试中需确保该Subject不会阻塞订阅执行。
修正后的测试用例代码
it('should subscribe to the store and update appRuleList and appRuleOptions on ngOnInit', () => { // 1. 构造符合IApplicationRule类型的测试数据 const mockApplicationData: IApplicationRule = { applicationRule: [ { "name": "ui", "place": "usa" } ] }; component.selectedName = 'test'; // 2. 正确模拟store的pipe返回流 spyOn(component['_store$'], 'pipe').and.returnValue(of(mockApplicationData)); // 3. 初始化组件的destroy Subject(如果是私有属性则直接赋值) component['destroy'] = new Subject<boolean>(); component.ngOnInit(); fixture.detectChanges(); // 4. 修正断言的期望值 expect(component.appRuleList).toEqual(mockApplicationData.applicationRule); expect(component.appRuleOptions).toEqual(['test/ui']); // 5. 结束订阅避免内存泄漏 component['destroy'].next(true); component['destroy'].complete(); });
更优方案:使用NgRx官方测试工具
如果项目用NgRx,推荐用provideMockStore来模拟store,更符合官方最佳实践,无需手动spy:
import { provideMockStore } from '@ngrx/store/testing'; // 在TestBed配置中添加 beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [AppComponent], providers: [ provideMockStore({ selectors: [ { selector: applicationRows, value: { applicationRule: [ { name: "ui", place: "usa" } ] } } ] }) ] }).compileComponents(); }); // 简化后的测试用例 it('should update appRuleList and appRuleOptions on ngOnInit', () => { component.selectedName = 'test'; component.ngOnInit(); fixture.detectChanges(); expect(component.appRuleList).toEqual([{ name: "ui", place: "usa" }]); expect(component.appRuleOptions).toEqual(['test/ui']); });
内容的提问来源于stack exchange,提问作者Goutm
相关产品推荐
相关产品推荐

