2

我正在尝试为非调度效果编写单元测试(基于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);
   });
});

如果添加以下行,则效果捕获动作并进入 switchmap + tap 中的逻辑:

expect(effects.initAuthFromLocalStorage$).toBeObservable();

尽管我收到此行的错误并且 效果的实际值(initAuthFromLocalStorage$)是一个对象而不是可观察的。

谢谢!

4

1 回答 1

1

阅读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);
});
于 2020-12-03T15:56:11.367 回答