首页 > 解决方案 > NGXS - 测试惰性选择器失败

问题描述

我们正在使用 ngxs,我们确实在与状态定义分开的文件中定义了一些惰性选择器

export class SectionSelectors {

  @Selector([CatalogState])
  static ById(state: CatalogModel) {
    return function getSectionById(id: number): Section {
      const selectedSection: Section = state.sections[id];
      return selectedSection;
    };
  }
}

我们有测试用例,比如

import { TestBed } from '@angular/core/testing';
import { Section } from '@miq-catalog/catalog';
import { NgxsModule, Store } from '@ngxs/store';
import { CatalogModel, CatalogState } from './catalog.state';
import { SectionSelectors } from './section.selectors';

describe('SectionSelectors', () => {

  it('should select the section by id', () => {
    const one: Section = { sectionId: 1, title: '', columns: [] };
    const two: Section = { sectionId: 2, title: '', columns: [] };
    const state: CatalogModel = {
      catalog: [],
      sections: { 1: one, 2: two },
      columns: {},
      catalogLoaded: true,
    };

    const selectionFunction = SectionSelectors.ById(state);

    const result = selectionFunction(1);
    expect(result).toBeDefined();
    expect(result).toBe(one);
    expect(result.sectionId).toBe(1);

    const result2 = selectionFunction(2);
    expect(result2).toBeDefined();
    expect(result2).toBe(two);
    expect(result2.sectionId).toBe(2);
  });
});

我们将状态传递给选择器但是我们得到了下一个错误

An error was thrown in afterAll
  Uncaught ReferenceError: Cannot access 'CatalogState' before initialization
  ReferenceError: Cannot access 'CatalogState' before initialization

我注意到,如果我将这些选择器移动到 CatalogState(@State 定义所在的位置),问题就解决了。但这迫使我们将所有选择器放在那里,我们认为最好将它们限定在自己的相关文件中,这样我们就不会“污染”混合选择器。

有没有办法修复测试用例?是否有人之前已经面对过这个 Lazy Selector 测试?

作为补充信息,这就是我们的州的样子

@State({
  name: 'Catalog',
  defaults: {
    catalogLoaded: false,
    columns: {},
    sections: {},
    catalog: [],
  },
})
export class CatalogState {
  constructor(private store: Store) {}

  @Action(RetrieveCatalogInfo)
  @Action(ChangeColumnConfig)
  @Action(ClearCatalog)
  public executeAction(ctx: StateContext<CatalogModel>, params: ExecutableAction<CatalogModel>) {
    return params.execute({ ctx, store: this.store });
  }
}

标签: javascriptangularngxs

解决方案


对于最新版本的 NGXS(自 v3.6.1 起),这应该不是问题。


推荐阅读