Тестирование эффектов NgRx 6
Я пытаюсь проверить эффекты ngrx в проекте Angular 6, я всегда получаю сообщение об ошибке:
Expected $[0].notification.kind = 'C' to equal 'N'.
Expected $[0].notification.hasValue = false to equal true.
Я попробовал этот пост https://brianflove.com/2018/06/28/ngrx-testing-effects/ и тот, что в документе ngrx. Есть ли какие-либо требования для тестирования эффектов с помощью ngrx 6? Ошибка не достаточно значима для меня. Может быть, у кого-то есть полный пример о том, как это сделать?
Вот мой эффект:
initData$: Observable<Action> = this.actions$.pipe(
ofType(INIT_DATA_ACTION),
switchMap((data: any) => {
return this.store.pipe(select(getAppDataResolved)).take(1).switchMap((resolved: any) => {
if (!resolved) {
return this.dataService.getInitData(this.loginService.user.id).switchMap((response: any) => {
return Observable.from([
new ItemsInitDataAction(response.userItems),
new InitDataResolvedAction(),
]);
});
} else {
return Observable.from([
new InitDataResolvedAction(),
]);
}
});
}),
);
и мой тест кармы:
it('should be created', () => {
expect(effects).toBeTruthy(); // got success
});
it('basic test', () => { // got error
const action = new appAction.InitDataAction();
const outcome = new appAction.InitDataResolvedAction();
actions.stream = hot('a', { a: action });
const expected = hot('a', { b: outcome });
expect(effects.initData$).toBeObservable(expected);
});
});
Заранее спасибо за помощь;-)
0 ответов
Я думаю, вам нужно вставить макет для селектора, следующая строка в консоли должна описывать что-то об отсутствующих данных селектора.
let store: Store<any>
class MockStore {
select(){}
}
TestBed.configureTestingModule({
providers: [
{
provide: Store,
useClass: MockStore
}
]
});
store = TestBed.get(Store);
А в тестовом наборе вы можете использовать Spy, чтобы предоставить вам любой кусок магазина, который вы хотите:
spyOn(store, 'select').and.returnValue(of(initialState));
В опечатке есть ожидание. Это должно быть "б" вместо "а"
const expected = hot('b', { b: outcome });
Я еще не смог пройти тестирование на мраморе.
Я использую Nrwl nx, так что мой тест эффектов выглядит так:
import { TestBed } from '@angular/core/testing';
import { Subject, ReplaySubject } from 'rxjs';
import { EffectsModule } from '@ngrx/effects';
import { StoreModule } from '@ngrx/store';
import { provideMockActions } from '@ngrx/effects/testing';
import { NxModule } from '@nrwl/nx';
import { DataPersistence } from '@nrwl/nx';
import { ChangePasswordEffects } from './change-password.effects';
import { ChangePassword, ChangePasswordSuccessful } from './change-password.actions';
import { HttpClientTestingModule } from '@angular/common/http/testing';
describe('ChangePasswordEffects', () => {
let actions: Subject<any>;
let effects: ChangePasswordEffects;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [NxModule.forRoot(), StoreModule.forRoot({}), EffectsModule.forRoot([]), HttpClientTestingModule],
providers: [ChangePasswordEffects, DataPersistence, provideMockActions(() => actions)]
});
effects = TestBed.get(ChangePasswordEffects);
});
describe('loadChangePassword$', () => {
it('should work', () => {
actions = new ReplaySubject(1);
actions.next(ChangePassword);
effects.loadChangePassword$.subscribe(result => {
expect(result).toEqual(ChangePasswordSuccessful);
});
});
});
});
И мой код выглядит так:
import { PasswordChangeError } from './../../models/password-change-error';
import { Injectable } from '@angular/core';
import { Effect, Actions } from '@ngrx/effects';
import { DataPersistence } from '@nrwl/nx';
import { ChangePasswordPartialState } from './change-password.reducer';
import {
ChangePassword,
ChangePasswordSuccessful,
ChangePasswordError,
ChangePasswordActionTypes
} from './change-password.actions';
import { ChangePasswordService } from '../../services/change-password/change-password.service';
import { map } from 'rxjs/operators';
@Injectable()
export class ChangePasswordEffects {
@Effect() loadChangePassword$ = this.dataPersistence.fetch(ChangePasswordActionTypes.ChangePassword, {
run: (action: ChangePassword, state: ChangePasswordPartialState) => {
return this.passwordService
.changePassword(action.newPassword, action.userId)
.pipe(map(res => new ChangePasswordSuccessful(res)));
},
onError: (action: ChangePassword, error: PasswordChangeError) => {
return new ChangePasswordError(error);
}
});
constructor(
private actions$: Actions,
private dataPersistence: DataPersistence<ChangePasswordPartialState>,
private passwordService: ChangePasswordService
) {}
}