如何在 angular 组件中测试 NGXS?

How to test NGXS in angular component?

我是 NGXS 的新手,在测试时我在所有测试用例中都遇到了错误。 我正在从商店获取数据: app.component.ts

    somedata: Idetail
    this.someData = this.store.selectSnapshot(State.details).
    this.data = this.someData.DATA;

但是我在每个测试用例上都遇到错误:

TypeError: Cannot read property 'DATA' of null

如果您想从存储中获取数据到组件中进行单元测试,请执行以下操作:

  • 在 TestBed.configureTesdtingModule 添加到您的进口 NgxsModule.forRoot([StateName])

  • 确保组件具有正确的选择器设置以在

  • 中获取数据
  • 在您的单元测试用例中获取 Store 实例:const store: Store = TestBed.get(Store);

  • 从测试用例中调度存储操作 store.dispatch(new AddToDo(toDo));

  • 检查组件的响应

有关更多信息,请访问文档 https://www.ngxs.io/recipes/unit-testing 我在 4 周前开始使用 NGXS 时发现它真的很有帮助 :)

您必须模拟商店才能在测试中使用它。

例如:

beforeEach(async(() => {
   TestBed.configureTestingModule({
      declarations: [MyComponent]
      imports: [NgxsModule.forRoot([])] // import real module without state
   });

   const store:Store = TestBed.get(Store);
   spyOn(store, 'select').and.returnValue(of(null)); // be sure to mock the implementation here
   spyOn(store, 'selectSnapshot').and.returnValue(null); // same here
}));

如果您可以提供更多代码 and/or stackblitz,那么我想您会得到更多帮助。

这似乎是一个奇怪的话题,但希望我能给出一些关于使用 Angular 组件对 NGXS 进行单元测试的技巧:

Imports NgxsModule.forRoot([StateName1, StateName2, ...]), and then add every constructor injection from StateName1 (and StateName2, ...) under TestBed.configureTestingModule providers (ensure you already had proper mocks for each injection) and this is really important.

这是我的例子:

TestBed.configureTestingModule({
      declarations: [MyComponent]
      imports: [NgxsModule.forRoot([NAME_OF_YOUR_TESTING_STATE])]
   });

await TestBed.compileComponents().then(async () => {
      fixture = TestBed.createComponent(NAME_OF_YOUR_TESTING_COMPONENT);
      component = fixture.componentInstance;
      fixture.detectChanges();

      store = TestBed.get(Store);
      store.reset(NAME_OF_YOUR_TESTING_STATE);
      actions$ = TestBed.get(Actions);
});

You should define store and actions$ object beforehand

let store: Store;
let actions$: Observable<any>;

毕竟,如果调度 ButtonChange 操作并更新 isButtonChanged,您可以测试以下内容:

public changeButton(value: string): void {
       this.store.dispatch(new ButtonChange(value));
       this.isButtonChanged = true;
}

我可以简单地实现它:

it('should segmentButtonChanged', () => {
        let actionDispatched = false;
        zip(actions$.pipe(ofActionDispatched(ChangeButton))).subscribe(() => (actionDispatched = true));

        const mockedString = 'hello there';
        component.changeButton(mockedString);

        expect(actionDispatched).toBeTruthy();
        expect(component.isButtonChanged).toBeTruthy();
});