如何在Angular组件中Mock NGRX Action?
如何在Angular组件测试中Mock NGRX Action(针对你的场景)
刚好做过类似的NGRX组件测试,给你梳理一下这个场景下的Mock方案,核心就是在测试环境里精准控制Store的dispatch行为和Action流,让组件能收到预期的success事件:
1. 准备测试依赖与配置测试模块
首先要导入NGRX官方提供的测试工具,用provideMockStore模拟Store、provideMockActions模拟Action流,替代真实的Store和Effects,配置到TestBed中:
import { ComponentFixture, TestBed } from '@angular/core/testing'; import { Store } from '@ngrx/store'; import { Actions } from '@ngrx/effects'; import { provideMockStore } from '@ngrx/store/testing'; import { provideMockActions } from '@ngrx/effects/testing'; import { hot } from 'jasmine-marbles'; // 导入你的组件、Action和数据类型 import { YourComponent } from './your.component'; import { action1, action1Success } from './your.actions'; import { SuccessObj } from './your.models'; describe('YourComponent', () => { let component: YourComponent; let fixture: ComponentFixture<YourComponent>; let actions$: Observable<any>; let store: Store; beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [YourComponent], // 导入组件依赖的Angular基础模块,比如CommonModule等 imports: [], providers: [ // 初始化Mock Store,initialState可根据业务场景自定义 provideMockStore({ initialState: {} }), // 提供可手动控制的Mock Action流 provideMockActions(() => actions$), ], }).compileComponents(); // 注入实例供测试使用 store = TestBed.inject(Store); actions$ = TestBed.inject(Actions); fixture = TestBed.createComponent(YourComponent); component = fixture.componentInstance; }); });
2. 编写测试用例:验证dispatch与订阅逻辑
接下来编写核心测试用例,模拟action1Success的发出,同时验证组件的初始化dispatch和成功事件处理逻辑:
it('should dispatch action1 on init and handle action1Success correctly', () => { // 1. 准备测试用的SuccessObj模拟数据 const mockSuccessData: SuccessObj = { // 填入你的测试数据,比如id: 1, content: 'test'等 }; // 2. 用jasmine-marbles的hot函数模拟异步Action流:1个时间帧后发出action1Success actions$ = hot('-a', { a: new action1Success(mockSuccessData) }); // 3. 监听Store的dispatch方法,验证是否调用了action1 const dispatchSpy = spyOn(store, 'dispatch'); // 4. 触发组件初始化(fixture.detectChanges()会自动调用ngOnInit) fixture.detectChanges(); // 5. 验证组件确实在初始化时dispatch了action1 expect(dispatchSpy).toHaveBeenCalledWith(new action1()); // 6. 验证组件处理成功事件后的业务逻辑 // 假设组件把成功数据存到了component.successResult属性里,根据你的实际代码调整 expect(component.successResult).toEqual(mockSuccessData); });
关键注意点
- 这里用
provideMockActions直接模拟了action1Success的发出,不需要启动真实的Effects,因为我们的测试目标是组件的行为,而非Effects本身的逻辑 hot函数用于模拟异步Action流,更贴近真实场景(Effects处理是异步的)- 如果你的组件订阅Action时用了
takeUntil等销毁操作符,记得在测试中正确处理组件销毁,避免内存泄漏
内容的提问来源于stack exchange,提问作者Gnesh23
相关产品推荐
相关产品推荐

