具有模拟用户输入的RxJs / Ngrx TestSheduler(Jasmine)

时间:2018-05-30 15:59:27

标签: angular jasmine rxjs ngrx jasmine-marbles

我正在角应用程序中测试Ngrx存储效果。作为副作用,我的一个效果是使用材质MatDialog组件弹出的模态。

我想要做的是运行一个测试,其中一个动作启动效果,触发mat对话框出现。然后我想测试点击是/否,然后继续检查所产生的动作(或缺少动作)。

我们正在使用rxjs-marbles来测试我们的商店。

RxJs似乎没有大量的例子,但我已经收集到我需要在这种情况下使用TestScheduler。不过,我不确定它是如何工作的。我正在做很多研究,并没有取得很大进展。

基本上,作为大理石,它看起来像这样:

-a-b-c

其中a是初始操作,b是对话框中用户点击的结果,c是结果(c是可选的,如果用户点击“否”,则不会产生任何结果。

我不是要求任何人编写我的代码,只是指出我正确的方向。我即将开始阅读TestScheduler的源代码,以便更好地理解它,因为我甚至不确定在这种情况下我应该使用它。

基本上,如何编写这样的测试,有可观察的流与使用大理石的模拟用户输入相结合?

1 个答案:

答案 0 :(得分:0)

所以我意识到我的做法是错误的。这是一个单元测试,而不是e2e测试,因此我不需要测试UI的特定功能。因此,我想出了以下测试:

it('should show a dialog, and do nothing if the user does not confirm',
      () => {
        const dialogRef = jasmine.createSpyObj('dialogRef', {
          afterClosed: of(false),
        });
        const action = new AppActions.PromptUserAction();
        matDialog.open.and.returnValue(dialogRef);

        actions = hot('a', { a: action });
        const expected = cold('', {});

        expect(effects.promptUserAction$).toBeObservable(expected);
        expect(matDialog.open).toHaveBeenCalled();
        expect(dialogRef.afterClosed).toHaveBeenCalled();
      });

在说明中:

  • 创建一个由模拟的MatDialog服务返回的dialogRef(在beforeEach Angular TestBed设置中完成,通过提供类似的间谍对象创建:

    {
      provide: MatDialog,
      useValue: jasmine.createSpyObj(
        'MatDialog',
        ['open'],
      ),
    },
    
  • 这会打开open方法,你会注意到openValue dialogRef的open调用,然后我们可以使用它作为间谍来返回我们想要的observable。非常简单,真的。

其余的测试很简单。希望这有助于某人 - 你不一定需要模拟点击,因为它隐含在流程中!