非调度效果的单元测试
unit test for a non-dispatching effect
我正在尝试为非调度效果编写单元测试(基于 ngrx 指南:https://ngrx.io/guide/effects/testing)
但由于未知原因,效果似乎没有捕捉到动作
而且我不明白我的测试有什么问题。
效果:
startLocalStorageSync$ = createEffect(() => this.actions$.pipe(
ofType(START_LOCAL_STORAGE_SYNC),
switchMap(() => {
return this.authService.authState$.pipe(
tap((authState) => {
this.localStorageService.set(AUTH_COOKIE, authState);
})
);
})
), {dispatch: false});
单元测试:
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
LocalStorageService,
AuthService,
AuthEffects,
provideMockActions(() => actions$)
]
});
effects = TestBed.inject(AuthEffects);
authService = TestBed.inject(AuthService);
localStorageService = TestBed.inject(LocalStorageService);
});
it('should call set to local storage', () => {
const setSpy : jasmine.Spy = spyOn(localStorageService, 'set');
actions$ = cold('a', {a: new AuthActions.StartLocalStorageSync()});
effects.startLocalStorageSync$.subscribe(()=>{
expect(setSpy).toHaveBeenCalled();
expect(setSpy).toHaveBeenCalledWith(AUTH_COOKIE, authState);
});
});
如果添加以下行,则effect 捕获动作并进入switchmap + tap 中的逻辑:
expect(effects.initAuthFromLocalStorage$).toBeObservable();
虽然我收到此行的错误并且 效果 (initAuthFromLocalStorage$) 是一个对象而不是可观察的。
谢谢!
阅读您提供的 link 中的 A non-dispatching Effect
后,请尝试以下操作:
import { of } from 'rxjs';
....
// mock your external dependencies for better control
let mockLocalStorageService: any;
let mockAuthService: any;
beforeEach(() => {
// create a spyObj with the optional name as first argument and
// public methods as an array of strings in the second argument
mockLocalStorageService = jasmine.createSpyObj('localStorageService', ['set']);
// make auth service into a simple object
mockAuthService = { authState$: of(true) }; // mock authState$ here
TestBed.configureTestingModule({
providers: [
{ provide: LocalStorageService, useValue: mockLocalStorageService },
{ provide: AuthService: useValue: mockAuthService },
AuthEffects,
provideMockActions(() => actions$)
]
});
effects = TestBed.inject(AuthEffects);
authService = TestBed.inject(AuthService);
localStorageService = TestBed.inject(LocalStorageService);
});
it('should call set to local storage', () => {
actions$ = of(new AuthActions.StartLocalStorageSync());
effects.startLocalStorageSync$.subscribe();
// authState is true therefore the true
expect(mockLocalStorageService.set).toHaveBeenCalledWith(AUTH_COOKIE, true);
});
我正在尝试为非调度效果编写单元测试(基于 ngrx 指南:https://ngrx.io/guide/effects/testing) 但由于未知原因,效果似乎没有捕捉到动作 而且我不明白我的测试有什么问题。
效果:
startLocalStorageSync$ = createEffect(() => this.actions$.pipe(
ofType(START_LOCAL_STORAGE_SYNC),
switchMap(() => {
return this.authService.authState$.pipe(
tap((authState) => {
this.localStorageService.set(AUTH_COOKIE, authState);
})
);
})
), {dispatch: false});
单元测试:
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
LocalStorageService,
AuthService,
AuthEffects,
provideMockActions(() => actions$)
]
});
effects = TestBed.inject(AuthEffects);
authService = TestBed.inject(AuthService);
localStorageService = TestBed.inject(LocalStorageService);
});
it('should call set to local storage', () => {
const setSpy : jasmine.Spy = spyOn(localStorageService, 'set');
actions$ = cold('a', {a: new AuthActions.StartLocalStorageSync()});
effects.startLocalStorageSync$.subscribe(()=>{
expect(setSpy).toHaveBeenCalled();
expect(setSpy).toHaveBeenCalledWith(AUTH_COOKIE, authState);
});
});
如果添加以下行,则effect 捕获动作并进入switchmap + tap 中的逻辑:
expect(effects.initAuthFromLocalStorage$).toBeObservable();
虽然我收到此行的错误并且 效果 (initAuthFromLocalStorage$) 是一个对象而不是可观察的。
谢谢!
阅读您提供的 link 中的 A non-dispatching Effect
后,请尝试以下操作:
import { of } from 'rxjs';
....
// mock your external dependencies for better control
let mockLocalStorageService: any;
let mockAuthService: any;
beforeEach(() => {
// create a spyObj with the optional name as first argument and
// public methods as an array of strings in the second argument
mockLocalStorageService = jasmine.createSpyObj('localStorageService', ['set']);
// make auth service into a simple object
mockAuthService = { authState$: of(true) }; // mock authState$ here
TestBed.configureTestingModule({
providers: [
{ provide: LocalStorageService, useValue: mockLocalStorageService },
{ provide: AuthService: useValue: mockAuthService },
AuthEffects,
provideMockActions(() => actions$)
]
});
effects = TestBed.inject(AuthEffects);
authService = TestBed.inject(AuthService);
localStorageService = TestBed.inject(LocalStorageService);
});
it('should call set to local storage', () => {
actions$ = of(new AuthActions.StartLocalStorageSync());
effects.startLocalStorageSync$.subscribe();
// authState is true therefore the true
expect(mockLocalStorageService.set).toHaveBeenCalledWith(AUTH_COOKIE, true);
});