如何对是否已分派动作进行单元测试?
例如,在LogoutService中,我有以下简单方法:
logout(username: string) {
store.dispatch([new ResetStateAction(), new LogoutAction(username)]);
}
我需要编写一个单元测试,以验证是否已分派了两个操作:
it('should dispatch ResetState and Logout actions', function () {
logoutService.logout();
// how to check the dispactched actions and their parameters?
// expect(...)
});
如何检查已调度的动作?
答案 0 :(得分:2)
正如@Garth Mason所说,您可以检查是否正在使用action streams调用动作。
1。创建变量actions$
describe('control-center.state', () => {
let actions$: Observable<any>;
// ...
});
2。使用可观察的
初始化变量actions$
// ...
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
NgxsModule.forRoot([AppState]),
NgxsModule.forFeature([ControlCenterState])
]
});
store = TestBed.get(Store);
actions$ = TestBed.get(Actions);
})
// ...
3。测试是否正在调用动作
使用操作符ofActionsDispatched()
函数从流中过滤您的操作,并使用完成的回调。
// ...
it('should call actions ResetStateAction and LogoutAction', async( () => {
store.dispatch([new ResetStateAction(), new LogoutAction()]);
actions$.pipe(ofActionDispatched(ResetStateAction, LogoutAction))
.subscribe((actions) => {
expect(actions).toBeTruthy();
});
}));
// ...
直到以上对beforeEach的调用中调用完函数,此规范才会启动。并且,只有在完成之前,此规范才能完成。
答案 1 :(得分:1)
@Brampage的答案为我返回了误报(angular7,ngxs 3.3)。
还有另一个问题,代码:
ofActionDispatched(ResetStateAction, LogoutAction)
似乎等于“告诉是否已调度ResetStateAction或LogoutAction”。
我尝试过这种方式:
3。测试是否正在调用动作
// ...
it('should call actions ResetStateAction and LogoutAction', async( () => {
let actionDispatched = false;
zip(
actions$.pipe(ofActionDispatched(ResetStateAction)),
actions$.pipe(ofActionDispatched(LogoutAction))
)
.subscribe( () => actionDispatched = true );
store.dispatch([new ResetStateAction(), new LogoutAction()])
.subscribe(
() => expect(actionDispatched).toBe(true)
);
}));
// ...
答案 2 :(得分:0)
我认为,在单元测试中,所有相关依赖项的实际实现都应被模拟,因此我们不应在此处包括任何实际存储。 在这里,我们为Store提供了一个茉莉间谍,并只是检查是否使用正确的参数调度了某些操作。这也可以用来提供存根数据。
describe('LogoutService', () => {
let storeSpy: jasmine.SpyObj<Store>;
beforeEach(() => {
storeSpy = jasmine.createSpyObj(['dispatch']);
TestBed.configureTestingModule({
providers: [LogoutService, { provide: Store, useValue: storeSpy }]
});
})
it('should dispatch Logout and Reset actions', () => {
storeSpy.dispatch.withArgs([
jasmine.any(ResetStateAction),
jasmine.any(LogoutAction)])
.and
.callFake(([resetAction, logoutAction]) => {
expect(resetAction.payload).toEqual({...something});
expect(logoutAction.payload).toEqual({...somethingElse});
});
TestBed.inject(LogoutService).logout();
});