Модульное тестирование - получение TypeError: Вы указали неверный объект, где ожидался поток
Я пытаюсь выполнить модульный тест, в котором эффект использует службу для извлечения результатов из API, а затем запускает либо действие успеха, либо действие ошибки. Я получаю ошибку TypeError: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.
, Не совсем уверен, что нужно изменить, чтобы это работало.
Включая проверку на наличие ошибок и соответствующий код.
угловатый
Angular CLI: 7.1.4
Node: 10.5.0
OS: win32 x64
Angular: 7.1.4
... animations, cli, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router
Package Version
-----------------------------------------------------------
@angular-devkit/architect 0.10.7
@angular-devkit/build-angular 0.10.7
@angular-devkit/build-optimizer 0.10.7
@angular-devkit/build-webpack 0.10.7
@angular-devkit/core 7.0.7
@angular-devkit/schematics 7.1.4
@angular/cdk 7.2.0
@angular/material 7.2.0
@ngtools/webpack 7.0.7
@schematics/angular 7.1.4
@schematics/update 0.11.4
rxjs 6.3.3
typescript 3.1.6
webpack 4.19.1
Тестовое задание
describe('ResultsEffects', () => {
let store: jasmine.SpyObj<Store<FeatureState>>;
let ebs: jasmine.SpyObj<EBSService>;
let snackbar: jasmine.SpyObj<SnackBarService>;
beforeEach(() => {
store = jasmine.createSpyObj('store', ['pipe']);
ebs = jasmine.createSpyObj('EBSService', ['getPollResults', 'getUserHasVoted', 'getSettings']);
snackbar = jasmine.createSpyObj('SnackBarService', ['notify']);
});
describe('fetchResults', () => {
it(`should dispatch 'FetchPanelResultsError'`, () => {
const fetchAction = new FetchPanelResults();
const error = { statusText: 'ERROR' };
const errorAction = new FetchPanelResultsError({ error: error.statusText });
const values = {
a: fetchAction,
e: errorAction
};
const source = cold('a', values);
const expected = cold('--e', values);
const actions = new Actions(source);
ebs.getPollResults.and.returnValue(throwError(error));
const effects = new ResultsEffects(
actions,
store,
snackbar,
ebs
);
expect(
effects.fetchResults$({
debounce: 20,
scheduler: getTestScheduler()
})
).toBeObservable(expected);
});
});
});
эффект
@Effect()
fetchResults$ = ({ debounce = 500, scheduler = asyncScheduler } = {}) => this.actions$.pipe(
ofType<SetPanelResults>(PanelResultsActionTypes.FETCH_PANEL_RESULTS),
// need alternate method for this
// withLatestFrom(this.featureState$),
// map(([_, state]) => state.twitch.token),
debounceTime(debounce, scheduler),
switchMap((token) =>
this.ebs.getPollResults(token).pipe(
map(res => new SetPanelResults(res.data.results)),
catchError(error => of(new FetchPanelResultsError({ error: error.statusText })))
)
)
)
обслуживание
getPollResults(token: string): Observable<PollResultsFetchData> {
const options = {
headers: ebsHeaders(token)
};
return this.http.get<PollResultsFetchData>(`${this.ebsURL}/poll/results`, options);
}
Обновление: добавлен debounce, чтобы вызвать ошибку с шариками. Еще нужна альтернатива withLatestFrom
,
2 ответа
На основании комментариев:
Проблема в том, что withLatest
from на самом деле ничего не возвращает, потому что у вас нет состояния функции. Это потому, что вы издеваетесь над магазином jasmine.createSpyObj('store', ['pipe'])
,
Чтобы решить эту проблему, используйте "реальное" хранилище ngrx или используйте хранилище макетов, которое было реализовано в NgRx 7.
Для меня эта ошибка стала происходить регулярно в течение нескольких месяцев (Angular 7) в Live Reload во время разработки. Я исправлял это, просто открывая браузер с паузой в несколько секунд.
Сегодня повторное открытие не помогло, и я иногда выяснил, что повторное сохранение одного из исходных файлов (даже без его фактического изменения) помогает, и ошибка исчезает. Повторное сохранение запускает перекомпиляцию проекта в памяти с помощью веб-пакета и перезагрузки в реальном времени