1

所以我有一个 NGXS 状态类,它有一个如下所示的 Action 和处理程序:

export interface TaggingStateModel {
  tagging: string;
}

export class UpdateTagging {
  static type = '[Tagging] UpdateTagging';
}

@State<TaggingStateModel>({
  name: 'tagging',
  defaults: {tagging: null}
})
export class TaggingState {
  constructor(public store: Store) {}

  @Action(UpdateTagging)
  onUpdateTagging(ctx: StateContext<TaggingStateModel>) {
    const activeFile: string = this.store.selectSnapshot(FileState.getActiveFile);

    ctx.setState({tagging: activeFile});
  }
}

因此,我的组件可以调度UpdateTagging操作,这将使用 FileState 中的一个选择器获取快照,如下所示:

export interface FileStateModel {
  activeFile: string;
}

@State<FileStateModel>({
  name: 'file',
  defaults: {activeFile: null}
})
export class FileState {
  @Selector()
  static getActiveFile(state: FileStateModel): string {
    return state.activeFile;
  }
}

现在,我开始为 编写单元测试TaggingState,并从如下简单的内容开始:

describe('TagAssignmentState', () => {

  let store: Store;
  const activeFile = 'activeFile';

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [NgxsModule.forRoot([TaggingState, FileState])]
    });
    store = TestBed.get(Store);

    store.reset({
      tagging:{
          tagging: undefined
      },
      file:{
          activeFile: fileGuid
      }
    });
  });

  it('UpdateTagging testing', async () => {
    await store.dispatch(new UpdateTagging()).toPromise();

    const taggingStateModel: TaggingStateModel = store.selectSnapshot(TaggingState);
    expect(taggingStateModel.tagging).toEqual(activeFile);
  });
})

所以这似乎工作......有时。但有时测试会失败,并出现错误Class constructor FileState cannot be invoked without 'new'。也许 1/6 的尝试会失败。无论我做什么,我都不会或多或少地经常发生错误。

在网上四处寻找有此错误的其他人,他们都表示这可能与我的编译器模块有关,我目前已设置esnext并希望保持这种状态。一件事建议将其转回 es5,但 angular 似乎不再支持这一点。

我已经尝试在同一个类中注释掉其他测试,看看这是否会影响事情,但它不会。我试过使用return await this.store.select(FileState.getActiveFile).toPromise(),但它只是偶尔返回undefined而不是字符串。如果我添加 a.pipe(filter(activeFile => !!activeFile))它永远不会发出任何东西并失败。

如果您需要更多关于此的上下文,我可以尝试提供,但在这一点上,老实说,我什至不确定什么是相关的。我能找到的最接近的事情是这个讨论,但我什至不确定它是否与同一件事有关,因为我没有做任何与APP_INITIALIZER.

4

1 回答 1

0

您应该遵循 NGXS 指南进行单元测试:https ://www.ngxs.io/recipes/unit-testing

按照该指南,对于这种情况,我将进行此测试:

describe('TagAssignmentState', () => {

  let store: Store;
  const activeFile = 'activeFile';

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [NgxsModule.forRoot([TaggingState, FileState])]
    });
    store = TestBed.get(Store);
    store.reset({
      tagging:{
          tagging: undefined
      },
      file:{
          activeFile: fileGuid
      }
    });
  }));

  it('UpdateTagging testing', () => {
  spyOn(store,'selectSnapshot').and.returnValue(activeFile);
  store.dispatch(new UpdateTagging());
  store.selectOnce(state => state.tagging).subscribe(
    (tag) => {
       expect(tag).toEqual(activeFile);
    }
  );
})

现在我认为这应该有效。

于 2019-11-28T15:03:17.237 回答