@ngrx/effects: 测试一个效果 returns empty()
@ngrx/effects: testing an effect returns empty()
我正在使用@ngrx/effects 4.1.1。我的效果是 returns 一个像这样的空可观察对象:
@Effect() showDialog$: Observable<Action> = this
.actions$
.ofType( ActionTypes.DIALOG_SHOW )
.map( ( action: DialogAction ) => action.payload )
.switchMap( payload => {
this.dialogsService.showDialog( payload.className );
return empty();
} );
我正尝试在 these guidelines 之后编写一个单元测试,以测试该效果是否会产生一个空的可观察对象。我有这个:
describe( 'DialogEffects', () => {
let effects: DialogEffects;
let actions: Observable<any>;
const mockDialogService = {
showDialog: sinon.stub()
};
beforeEach( () => {
TestBed.configureTestingModule( {
providers: [
DialogEffects, provideMockActions( () => actions ),
{
provide: DialogsService,
useValue: mockDialogService
}
]
} );
effects = TestBed.get( DialogEffects );
} );
describe( 'showDialog$', () => {
it( 'should return an empty observable', () => {
const dialogName = 'testDialog';
const action = showDialog( dialogName );
actions = hot( '--a-', { a: action } );
const expected = cold( '|' );
expect( effects.showDialog$ ).toBeObservable( expected );
} );
} );
} );
然而,Karma (v1.7.1) 抱怨:
Expected [ ] to equal [ Object({ frame: 0, notification: Notification({ kind: 'C', value: undefined, error: undefined, hasValue: false }) }) ].
如何测试 returns empty()
的效果?我尝试使用 dispatch: false
修改效果元数据,但这没有效果。
想法?
问题是您将实际结果与 cold('|')
进行比较。
cold('|')
中的竖线表示可观察流的完成。但是,您的效果不会完成。 empty()
observable 确实完成了,但是从 switchMap
返回 empty()
只是看到 observable 合并到 effect observable 的流中——它没有完成 effect observable。
相反,您应该将实际结果与 cold('')
- 一个不发出任何值且未完成的可观察对象进行比较。
最好的方法是在 effect 中使用 dispatch false 并更改 swicthMap 以进行点击
@Effect({dispatch: false}) showDialog$ = this.actions$.pipe(
ofType( ActionTypes.DIALOG_SHOW ),
map( ( action: DialogAction ) => action.payload ),
tap( payload =>
this.dialogsService.showDialog( payload.className )
));
要测试它,您可以像
describe( 'showDialog$', () => {
it( 'should return an empty observable', () => {
const dialogName = 'testDialog';
const action = showDialog( dialogName );
actions = hot( '--a-', { a: action } );
expect(effects.showDialog$).toBeObservable(actions);
// here use mock framework to check the dialogService.showDialog is called
} );
} );
请注意我使用 toBeObservable(actions) 的原因,那是因为由于 disptach false 这个效果不会产生任何东西,所以 actions 和以前一样,你通过调用 toBeObservable(actions) 获得的是使测试同步,因此您可以在它之后检查您的服务是否使用 jasmine 或 ts-mockito
等模拟框架调用
要测试效果不派发,您可以使用 getEffectsMetadata 函数断言它的元数据:
expect(getEffectsMetadata(effects).deleteSnapshotSuccess$?.dispatch).toBe(false)
以上已经用ngrx 9.0.0测试过。由于所有 observables 都会发出,而不管 dispatch
,像 expect(effects.effect$).toBeObservable(cold(''))
这样的检查不会产生预期的结果。
我正在使用@ngrx/effects 4.1.1。我的效果是 returns 一个像这样的空可观察对象:
@Effect() showDialog$: Observable<Action> = this
.actions$
.ofType( ActionTypes.DIALOG_SHOW )
.map( ( action: DialogAction ) => action.payload )
.switchMap( payload => {
this.dialogsService.showDialog( payload.className );
return empty();
} );
我正尝试在 these guidelines 之后编写一个单元测试,以测试该效果是否会产生一个空的可观察对象。我有这个:
describe( 'DialogEffects', () => {
let effects: DialogEffects;
let actions: Observable<any>;
const mockDialogService = {
showDialog: sinon.stub()
};
beforeEach( () => {
TestBed.configureTestingModule( {
providers: [
DialogEffects, provideMockActions( () => actions ),
{
provide: DialogsService,
useValue: mockDialogService
}
]
} );
effects = TestBed.get( DialogEffects );
} );
describe( 'showDialog$', () => {
it( 'should return an empty observable', () => {
const dialogName = 'testDialog';
const action = showDialog( dialogName );
actions = hot( '--a-', { a: action } );
const expected = cold( '|' );
expect( effects.showDialog$ ).toBeObservable( expected );
} );
} );
} );
然而,Karma (v1.7.1) 抱怨:
Expected [ ] to equal [ Object({ frame: 0, notification: Notification({ kind: 'C', value: undefined, error: undefined, hasValue: false }) }) ].
如何测试 returns empty()
的效果?我尝试使用 dispatch: false
修改效果元数据,但这没有效果。
想法?
问题是您将实际结果与 cold('|')
进行比较。
cold('|')
中的竖线表示可观察流的完成。但是,您的效果不会完成。 empty()
observable 确实完成了,但是从 switchMap
返回 empty()
只是看到 observable 合并到 effect observable 的流中——它没有完成 effect observable。
相反,您应该将实际结果与 cold('')
- 一个不发出任何值且未完成的可观察对象进行比较。
最好的方法是在 effect 中使用 dispatch false 并更改 swicthMap 以进行点击
@Effect({dispatch: false}) showDialog$ = this.actions$.pipe(
ofType( ActionTypes.DIALOG_SHOW ),
map( ( action: DialogAction ) => action.payload ),
tap( payload =>
this.dialogsService.showDialog( payload.className )
));
要测试它,您可以像
describe( 'showDialog$', () => {
it( 'should return an empty observable', () => {
const dialogName = 'testDialog';
const action = showDialog( dialogName );
actions = hot( '--a-', { a: action } );
expect(effects.showDialog$).toBeObservable(actions);
// here use mock framework to check the dialogService.showDialog is called
} );
} );
请注意我使用 toBeObservable(actions) 的原因,那是因为由于 disptach false 这个效果不会产生任何东西,所以 actions 和以前一样,你通过调用 toBeObservable(actions) 获得的是使测试同步,因此您可以在它之后检查您的服务是否使用 jasmine 或 ts-mockito
等模拟框架调用要测试效果不派发,您可以使用 getEffectsMetadata 函数断言它的元数据:
expect(getEffectsMetadata(effects).deleteSnapshotSuccess$?.dispatch).toBe(false)
以上已经用ngrx 9.0.0测试过。由于所有 observables 都会发出,而不管 dispatch
,像 expect(effects.effect$).toBeObservable(cold(''))
这样的检查不会产生预期的结果。