簡體   English   中英

NGXS:store.reset 在 Jasmine 單元測試中禁用調度程序

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM