我正在使用@ ngrx / effects 4.1.1。我有一个效果,返回一个像这样的空observable:
@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之后编写一个单元测试,它将测试该效果产生一个空的observable。我有这个:
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)抱怨说:
期望[]等于[Object({frame:0,notification:Notification({kind:&#39; C&#39;,value:undefined,error:undefined,hasValue:false})})]。< / p>
如何测试效果是否返回empty()
?我尝试使用dispatch: false
修改效果元数据,但这没有效果。
想法?
答案 0 :(得分:5)
问题是您要将实际结果与200px
进行比较。
cold('|')
中的管道字符表示可观察流的完成。但是,您的效果将无法完成。 cold('|')
observable确实完成了,但是从empty()
返回empty()
只是看到observable合并到效果可观察的流中 - 它没有完成可观察的效果。
相反,您应该将实际结果与switchMap
进行比较 - 一个不会发出任何值但未完成的观察结果。
答案 1 :(得分:1)
做到这一点的最佳方法是在效果中使用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 );
return empty();
} ));
要进行测试,您可以像
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导致此效果不会产生任何结果,因此action与以前相同,通过调用toBeObservable(actions)获得的结果是使测试同步,因此您可以在之后检查您的服务是否已通过茉莉或ts-mockito之类的模拟框架进行调用
答案 2 :(得分:1)
要测试效果是否未调度,可以使用getEffectsMetadata函数针对其元数据进行断言:
expect(getEffectsMetadata(effects).deleteSnapshotSuccess$?.dispatch).toBe(false)
以上已通过ngrx 9.0.0测试。由于所有可观察物都发出而与dispatch
无关,因此expect(effects.effect$).toBeObservable(cold(''))
之类的检查不会产生预期的结果。