RxJs/Ngrx 具有模拟用户输入的 TestSheduler (Jasmine)
RxJs/Ngrx TestSheduler with simulated user input (Jasmine)
我正在 angular 应用程序中测试 Ngrx 存储效果。作为副作用,我的一个效果有一个使用 material MatDialog 组件弹出的模式。
我想做的是 运行 一个测试,其中效果由一个动作启动,触发垫对话框出现。然后我想测试单击 yes/no,然后继续检查结果操作(或缺少操作)。
我们正在使用 rxjs-marbles 来测试我们的商店。
RxJs 似乎并没有大量的例子,但我已经收集到我需要为这种类型的场景使用 TestScheduler。不过,我不确定它是如何工作的。我正在做很多研究,但没有取得很大进展。
基本上,作为弹珠,它看起来像这样:
-a-b-c
其中 a
是初始操作,b
是用户在对话框中的点击,c
是结果(c
是可选的,如果用户点击 'no',则不会有结果操作。
我不要求任何人编写我的代码,只是为我指出正确的方向。我即将开始阅读 TestScheduler 的源代码以更好地理解它,因为我什至不确定在这种情况下我是否应该使用它。
基本上,如何编写这样的测试,其中有可观察的流与使用弹珠的模拟用户输入相结合?
所以我意识到我的做法是错误的。这是一个单元测试,而不是 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();
});
在解释中:
创建一个 dialogRef,它将被模拟的 MatDialog 服务 return 编辑(在 beforeEach Angular TestBed 设置中完成,通过提供如下所示的间谍对象创建:
{
provide: MatDialog,
useValue: jasmine.createSpyObj(
'MatDialog',
['open'],
),
},
这对 open 方法存根,您会注意到 open 调用是对 returnValue dialogRef 进行的,然后我们可以将其用作 return 的间谍我们想要的可观察对象。很简单,真的。
测试的其余部分很简单。希望这对某些人有所帮助——您不一定需要模拟点击,因为它隐含在流程中!
我正在 angular 应用程序中测试 Ngrx 存储效果。作为副作用,我的一个效果有一个使用 material MatDialog 组件弹出的模式。
我想做的是 运行 一个测试,其中效果由一个动作启动,触发垫对话框出现。然后我想测试单击 yes/no,然后继续检查结果操作(或缺少操作)。
我们正在使用 rxjs-marbles 来测试我们的商店。
RxJs 似乎并没有大量的例子,但我已经收集到我需要为这种类型的场景使用 TestScheduler。不过,我不确定它是如何工作的。我正在做很多研究,但没有取得很大进展。
基本上,作为弹珠,它看起来像这样:
-a-b-c
其中 a
是初始操作,b
是用户在对话框中的点击,c
是结果(c
是可选的,如果用户点击 'no',则不会有结果操作。
我不要求任何人编写我的代码,只是为我指出正确的方向。我即将开始阅读 TestScheduler 的源代码以更好地理解它,因为我什至不确定在这种情况下我是否应该使用它。
基本上,如何编写这样的测试,其中有可观察的流与使用弹珠的模拟用户输入相结合?
所以我意识到我的做法是错误的。这是一个单元测试,而不是 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();
});
在解释中:
创建一个 dialogRef,它将被模拟的 MatDialog 服务 return 编辑(在 beforeEach Angular TestBed 设置中完成,通过提供如下所示的间谍对象创建:
{ provide: MatDialog, useValue: jasmine.createSpyObj( 'MatDialog', ['open'], ), },
这对 open 方法存根,您会注意到 open 调用是对 returnValue dialogRef 进行的,然后我们可以将其用作 return 的间谍我们想要的可观察对象。很简单,真的。
测试的其余部分很简单。希望这对某些人有所帮助——您不一定需要模拟点击,因为它隐含在流程中!