[英]NGXS : store.reset disables dispatchers in Jasmine unit tests
在使用 Jasmine 對我的 NGXS 存儲進行單元測試時,我遇到了意外行為的問題。
在這里,我正在嘗試測試 DeleteAlerts 操作:
@Action(DeleteAlerts)
deleteAlerts(ctx: StateContext<AlertStateModel>, action: DeleteAlerts) {
return this.alertService.deleteAlerts(action.alertIds).pipe(
map(response => {
if (response.ok) {
action.alertIds.forEach(alertId => {
ctx.setState(patch({
alerts: removeItem<UniqueAlert>(alert => alert.alertIds.includes(alertId))
}));
});
} else {
throw new Error('Server failed to respond.');
}
}
));
}
但必須首先用虛擬數據填充存儲。
我創建了這個模擬:
const alertsMock = new Alerts({
alerts: [new UniqueAlert({alertIds: ['test1']}),
new UniqueAlert({alertIds: ['test2']}),
new UniqueAlert({alertIds: ['test3']})]
});
我的商店是這樣的:
export interface AlertStateModel {
alerts: UniqueAlert[];
}
然后我嘗試用模擬填充商店:
store.reset({alerts: alertsMock.alerts})
但是,當我在測試中執行此操作時,調用store.dispatch(new DeleteAlerts(alertIds))
時不會調度DeleteAlerts
操作
這是我不明白的部分:當將store.reset
方法替換為GetAlerts
調度時,該操作會調度,該調度旨在從模擬服務加載警報:
GetAlerts 操作:
@Action(GetAlerts)
public getAlerts(ctx: StateContext<AlertStateModel>) {
return this.alertService.getAlerts().pipe(
tap(fetchedAlerts => {
ctx.setState({alerts: fetchedAlerts.alerts});
})
);
}
該測試通過:
it('should delete one alert from the store when DeleteAlerts is dispatched', () => {
spyOn(alertService, 'getAlerts').and.returnValue(of(alertsMock));
store.dispatch(new GetAlerts());
spyOn(alertService, 'deleteAlerts').and.returnValue(of(new HttpResponse({status: 200})));
store.dispatch(new DeleteAlerts(['test2']));
store.selectOnce(AlertState).subscribe(data => {
expect(data.alerts).toEqual(alertsMock.alerts.filter(alert => !alert.alertIds.includes('test2')));
});
});
});
該測試不會:
it('should delete one alert from the store when DeleteAlerts is dispatched', () => {
store.reset({alerts: alertsMock.alerts});
spyOn(alertService, 'deleteAlerts').and.returnValue(of(new HttpResponse({status: 200})));
store.dispatch(new DeleteAlerts(['test2']));
store.selectOnce(AlertState).subscribe(data => {
expect(data).toEqual(alertsMock.alerts.filter(alert => !alert.alertIds.includes('test2')));
});
});
最重要的是,您可能已經注意到我的期望是data
,而不是data.alerts
非功能測試。 這是我想了解的另一種行為,因為選擇器應返回 state,其中包含嵌套alerts
object。
為什么這兩個測試不等效,為什么選擇器在使用store.reset
填充存儲時不返回預期的 object?
關於為什么alertsMock
包含嵌套的alerts
object; 也就是alertService返回的數據格式。
看起來您沒有將商店快照擴展到測試重置中。 文檔沒有明確說明要這樣做,但是當我以這種方式重置時,我自己的測試通過了。
describe('the test suite', () => { let store: Store; beforeEach(() => { store = TestBed.inject(Store); store.reset({...store.snapshot(), DESIRED_STATE }) }); it('must do the test', () => { store.reset({...store.snapshot(), NEW_DESIRED_STATE }) }); });
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.