我正在使用以下设置编写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());
}
);
}
我可以在被拒绝的回调中看到日志(在其他测试中也可以看到),但是期望没有交互就失败了。我的假设是在 Promis范围中模拟this.store$.dispatch
就是问题所在。
这个假设正确吗?如何进行此测试?
答案 0 :(得分:0)
根本原因是,调用服务并执行console.log
时,Promise尚未解决。这是由于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());
});