【问题标题】:NGRX effect not executing when running tests using Jasmine marbles使用 Jasmine 弹珠运行测试时未执行 NGRX 效果
【发布时间】:2021-04-07 02:57:20
【问题描述】:

您好,我是 NGRX 的新手,正在尝试为我创建的效果编写测试,但是效果功能似乎从未真正运行过。

我要测试的效果是:

compelteAuthentication$ = createEffect(() => this.actions$.pipe(
    ofType(fromActions.completeAuthentication),
    switchMap(() => from(this.authService.completeAuthentication()).pipe(
      map(user => fromActions.authenticationSuccess({ value: user.state})),
      catchError(err => of(fromActions.authenticationFailed(err)))
    ))
  ));

目前测试的版本如下:

import { UserEffects } from './user.effects';
import { AuthService } from './../../core/services/auth.service';
import { ApiServiceMock, ApplicationInsightServiceMock, AppSettingsServiceMock, AuthServiceMock, RouterMock, UserServiceMock } from './../../../testing-utils/mocks/service-mocks';
import { TestBed } from '@angular/core/testing';
import { Action } from '@ngrx/store';
import { provideMockActions } from '@ngrx/effects/testing';
import { Observable } from 'rxjs';
import * as userActions from '../actions/user.actions';
import { cold, hot } from 'jasmine-marbles';
import { User } from 'oidc-client';

let actions$ = new Observable<Action>();
let completeAuthSpy: jasmine.Spy;
let userEffects: UserEffects;

beforeEach(() => {
  completeAuthSpy = jasmine.createSpy();

  TestBed.configureTestingModule({
    providers: [
      provideMockActions(() => actions$),
      UserEffects,
      AppSettingsServiceMock,
      // AuthServiceMock,
      ApiServiceMock,
      UserServiceMock,
      RouterMock,
      ApplicationInsightServiceMock,
      {
        provide: AuthService,
        usevalue: {
          completeAuthentication: completeAuthSpy
        }
      }
    ],
  });

  userEffects = TestBed.inject(UserEffects);
});

describe('UserEffects', () => {
  describe('CompleteAuthentication', () => {
    it('Should call success action', () => {
      const userState = new User({
          id_token: 'TestID',
          session_state: 'TestState',
          access_token: 'TestToken',
          refresh_token: 'TestRefreshToken',
          token_type: 'TestTokenType',
          scope: 'TestScope',
          profile: {} as any,
          expires_at: 6,
          state: undefined,
      });

      const outcome = userActions.authenticationSuccess({ value: userState.state });
      const response = cold('-a|', { a: userState });
      const expected = cold('--b', { b: outcome });
      completeAuthSpy.and.returnValue(response.toPromise());

      actions$ = hot('-c', { c: userActions.completeAuthentication });

      expect(userEffects.compelteAuthentication$).toBeObservable(expected);
      expect(completeAuthSpy).toHaveBeenCalled();
    });
  });
});

因此,当运行上述测试时,第一个期望失败并返回 [] 而不是预期的操作。

知道我在这里缺少什么吗?

【问题讨论】:

    标签: angular ngrx ngrx-effects angular-test jasmine-marbles


    【解决方案1】:

    rxjs observables 是惰性的。这意味着代码在订阅时执行。在您的测试中expect(userEffects.compelteAuthentication$).toBeObservable(expected); 正在订阅。所以只需交换expects 的顺序,一切都会好起来的

          actions$ = hot('-c', { c: userActions.completeAuthentication });
    
          expect(userEffects.compelteAuthentication$).toBeObservable(expected);
          expect(completeAuthSpy).toHaveBeenCalled();
    

    【讨论】:

    • 试过了,userEffects.compelteAuthentication$ 返回一个空白数组。所以我手动订阅了它,看起来 authService.completeAuthentication() 仍然没有被调用
    • 似乎忘记了大括号。它应该是 userActions.completeAuthentication**()**
    • 我已经尝试过了,它会抛出一个错误,因为它不是一个函数
    • 您的测试需要调试
    • 是的,我试过了,我手动订阅了效果,它返回了正确的操作。然而,“期望”声明却没有。
    猜你喜欢
    • 1970-01-01
    • 2018-01-04
    • 2019-02-06
    • 2020-02-25
    • 2019-04-20
    • 1970-01-01
    • 2021-09-14
    • 2019-12-15
    • 2018-11-02
    相关资源
    最近更新 更多