【问题标题】:How I can test ngrx effects using jasmine marbles?如何使用茉莉弹珠测试 ngrx 效果?
【发布时间】:2019-04-28 18:23:00
【问题描述】:

我无法测试 NgRx 效果。你能帮帮我吗?

朋友,请帮帮我。我想测试一些效果,但我不能。我收到错误“预期 $[0].notification.value.payload 是一种对象,但用户({名称:'1212',角色:['somerole']})”。 我不明白哪里错了。

效果:

@Injectable({
  providedIn: 'root'
})
@Injectable()
export class AuthEffects {

  constructor(
    private actions$: Actions,
    private rootService: RootService,
    private router: Router,
  ) {
  }

  @Effect()
  authUser$: Observable<any> = this.actions$.pipe(
    ofType(authActions.FETCHING),
    map((action: authActions.Fetching) => action.payload),
    switchMap((paylod: UserRequest) => this.rootService.login(paylod)
        .pipe(
          map((value) => {
            const {sub, authorities} = value;
            this.router.navigate(['/customers-list']);
            return new authActions.Success(new User(sub, authorities));
          }),
          catchError(() => of(new authActions.Fail('wrong username or password')))
        )
    )
  );
}

规格:

describe('AuthEffects', () => {
  let effects: AuthEffects;
  let rootService: jasmine.SpyObj<RootService>;
  let actions: Observable<any>;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [HttpClientTestingModule, RouterTestingModule],
      providers: [
        RootService,
        AuthEffects,
        provideMockActions(() => actions),
        {
          provide: RootService,
          useValue: {
            login: jasmine.createSpy()
          }
        }
      ]
    });

    effects = TestBed.get(AuthEffects);
    rootService = TestBed.get(RootService);
  });

  it('should work', () => {
    const userRequest: UserRequest = {
      name: '1212',
      password: 'alsj'
    };
    const userResponse: UserResponse = {
      sub: '1212',
      authorities: ['somerole']
    };
    const editedUser: User = {
      name: '1212',
      roles: ['somerole']
    };
    const action = new authActions.Fetching(userRequest);
    const completion = new authActions.Success(editedUser);

    actions = hot('-a', {a: action});
    const response = cold('-a|', {a: userResponse});
    rootService.login.and.returnValue(response);
    const expected = cold('--b', {b: completion});

    expect(effects.authUser$).toBeObservable(expected);
  });
});

我试着按照一些例子来做,但有什么不对。

【问题讨论】:

    标签: jasmine karma-runner ngrx jasmine-marbles


    【解决方案1】:

    您必须对在测试中设置期望块的方式进行微小的更改。请尝试以下操作:

    effects.authUser$.subscribe(actionSent => {
     expect(actionSent).toBeObservable(expected)
    })
    

    而不是

    expect(effects.authUser$).toBeObservable(expected);
    

    我希望这对你有用。

    【讨论】:

    • 不错的尝试,但我收到错误:“未捕获的 TypeError:actual.subscribe 不是抛出的函数”
    • 我得到同样的错误,但找不到/不明白问题所在。你知道在这种情况下到底是什么问题吗?
    • 这将不起作用,因为订阅的 Observable 不再是 Observable。您可以使用“toBe”订阅并检查,是的,但不能使用“toBeObservable”。然后您也无法检查返回的操作。大理石测试实际上不需要订阅。我有打字丢失的同样问题。我真的很想有一个类似弹珠的类型假设:(。
    【解决方案2】:

    似乎构造函数打破了这个。如果我在没有构造函数的情况下更改效果代码 - 它的工作原理

      @Effect()
      authUser$: Observable<any> = this.actions$.pipe(
        ofType(authActions.FETCHING),
        map((action: authActions.Fetching) => action.payload),
        switchMap((paylod: UserRequest): any => this.rootService.login(paylod)
            .pipe(
              map((value: UserResponse) => {
                const {sub, authorities} = value;
                return new authActions.Success({
                  name: sub,
                  roles: authorities
                });
              }),
              catchError(() => of(new authActions.Fail('wrong username or password')))
            )
        )
      );
    

    【讨论】:

    • 回答你自己的问题很好,但我已经编辑了你问哪里出错的最后一点。您不应该在答案中提问,因为事情很快就会变得混乱,并且很难弄清楚哪个答案与其他答案相关。如果您仍然想知道出了什么问题,您应该发布另一个问题(链接到此问题以供参考)。 From Review
    猜你喜欢
    • 2019-02-04
    • 2021-09-14
    • 2020-01-19
    • 2021-04-07
    • 2023-03-15
    • 2020-11-25
    • 2020-08-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多