问题描述
嗨,我是 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,// AuthServiceMock,ApiServiceMock,UserServiceMock,{
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();
});
});
});
所以当上面的测试运行时,第一个期望失败,它返回 []
而不是预期的动作。
知道我在这里遗漏了什么吗?
解决方法
rxjs observables 是惰性的。这意味着代码在订阅时执行。在您的测试中,expect(userEffects.compelteAuthentication$).toBeObservable(expected);
正在订阅。所以只需交换 expect
的顺序,一切都会好的
actions$ = hot('-c',{ c: userActions.completeAuthentication });
expect(userEffects.compelteAuthentication$).toBeObservable(expected);
expect(completeAuthSpy).toHaveBeenCalled();