angular - Angular spyOn ngrx/store 在 Promise 范围内
问题描述
我正在使用以下设置编写带有 Angular TestBed 的测试:
let cacheService: CacheService;
let store: Store<PsaAppState>;
let service: ConfigService;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
ConfigService,
{ provide: TranslateService, useValue: getMock(TranslateService) },
{ provide: CacheService, useValue: getMock(CacheService) },
{ provide: Store, useValue: getMock(Store) }
]
});
const injector: TestBed = getTestBed();
service = injector.get(ConfigService);
cacheService = injector.get(CacheService);
store = injector.get(Store);
});
测试看起来像这样:
it('Should dispatch FetchFeatureConfigAction when promise is rejected', () => {
spyOn(store, 'dispatch').and.stub();
spyOn(cacheService, 'getRawItem').and.returnValue(Promise.reject('error'));
service.getFeatureConfig();
expect(store.dispatch).toHaveBeenCalledTimes(1);
expect(store.dispatch).toHaveBeenCalledWith(new FetchFeatureConfigAction());
});
它测试的代码如下所示:
getFeatureConfig() {
console.log('###Service called!!!');
this.cacheService.getRawItem('APP_STATE_NAME').then(
(appState: PsaAppState) => {
console.log('###Resolve with ', appState);
!isNil(appState.featureConfigState.featureConfig)
? this.store$.dispatch(new FetchFeatureConfigSuccessAction(appState.featureConfigState.featureConfig))
: this.store$.dispatch(new FetchFeatureConfigAction());
},
err => {
console.log('###Rejected with ', err);
this.store$.dispatch(new FetchFeatureConfigAction());
}
);
}
我可以在被拒绝的回调中看到日志(也可以在其他测试的已解决)中看到日志,但是期望失败且没有交互。我的假设是this.store$.dispatch
在Promis 范围内进行模拟是问题所在。
这个假设是否正确,我怎样才能使这个测试运行?
解决方案
根本原因是当服务被调用并被执行时,Promise 还没有解决console.log
。这是由于 Javascript事件循环处理异步请求的方式。
错误情况的修复如下:
it('Should dispatch FetchFeatureConfigAction when promise is rejected', () => {
spyOn(store, 'dispatch').and.stub();
const expectedPromise = Promise.reject('error');
spyOn(cacheService, 'getRawItem').and.returnValue(expectedPromise);
service.determineFeatureConfig();
expectedPromise.catch(() => {
expect(store.dispatch).toHaveBeenCalledTimes(1);
expect(store.dispatch).toHaveBeenCalledWith(new FetchFeatureConfigAction());
});
});
我将 Promise 提取到一个变量中,然后在catch中期望工作正常。
对于好的情况,解决方案可以使用then或async/await语法。后者的示例如下所示:
it('Should dispatch FetchFeatureConfigAction when promise is resolved', async () => {
spyOn(store, 'dispatch').and.stub();
const expectedPromise = Promise.resolve('success');
spyOn(cacheService, 'getRawItem').and.returnValue(expectedPromise);
service.determineFeatureConfig();
await expectedPromise;
expect(store.dispatch).toHaveBeenCalledTimes(1);
expect(store.dispatch).toHaveBeenCalledWith(new FetchFeatureConfigAction());
});
推荐阅读
- angular - 检查嵌入内容的插槽是否为空
- python - 根据一组值检查相等性
- c++ - 在视觉工作室中构建代码时,我面临错误,.h 文件丢失
- c - ffmpeg c api中的av_register_all()与avcodec_register_all()有什么区别?
- javascript - 如何从 javascript 中的变量创建对象属性?
- batch-file - 将数值转换回字母
- unity3d - 在 Unity 中使用 HiDPI 在 Mac 上获取 Retina 屏幕分辨率
- html - 调整窗口大小时将复选框位置保留在表单中
- nonlinear-optimization - R (NLOPTR - COBYLA) 非线性优化中的二元约束
- sql - 数据转换 Nvarchar 到 Money