RxJs debounce генерирует событие сразу во время тестов - PullRequest
0 голосов
/ 05 марта 2019

Я пытаюсь написать тестовую функцию для эпопеи, наблюдаемой в редуксе. Эпопея прекрасно работает внутри приложения, и я могу проверить, правильно ли она снимает действия и ждет 300 мсек перед отправкой. Но по какой-то причине, пока я пытаюсь протестировать его с шуткой, оператор debounce срабатывает немедленно Поэтому мой контрольный пример, чтобы убедиться, что debounce работает, не удался.

Это тестовый пример

it('shall not invoke the movies service neither dispatch stuff if the we invoke before 300ms', done => {
    const $action = ActionsObservable.of(moviesActions.loadMovies('rambo'));

    loadMoviesEpic($action).subscribe(actual => {
        throw new Error('Should not have been invoked');
    });

    setTimeout(() => {
        expect(spy).toHaveBeenCalledTimes(0);
        done();
    }, 200);

});

а это эпопея

import { Observable, interval } from 'rxjs';
import { combineEpics } from 'redux-observable';

import 'rxjs/add/operator/switchMap';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/debounce';
import 'rxjs/add/operator/filter';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/from';
import 'rxjs/add/observable/of';
import 'rxjs/add/observable/interval';
import 'rxjs/add/observable/concat';

import actionTypes from 'actions/actionTypes';
import * as moviesService from 'services/moviesService';
import * as moviesActions from 'actions/moviesActions';

const DEBOUNCE_INTERVAL_IN_MS = 300;
const MIN_MOVIES_SEARCH_LENGTH = 3;

export function loadMoviesEpic($action) {
  return $action
    .ofType(actionTypes.MOVIES.LOAD_MOVIES)
    .debounce(() => Observable.interval(DEBOUNCE_INTERVAL_IN_MS))
    .filter(({ payload }) => payload.length >= MIN_MOVIES_SEARCH_LENGTH)
    .switchMap(({ payload }) => {
      const loadingAction = Observable.of(moviesActions.loadingMovies());

      const moviesResultAction = Observable.from(
        moviesService.searchMovies(payload)
      )
        .map(moviesResultList => moviesActions.moviesLoaded(moviesResultList))
        .catch(err => Observable.of(moviesActions.loadError(err)));

      return Observable.concat(loadingAction, moviesResultAction);
    });
}

const rootEpic = combineEpics(loadMoviesEpic);

export default rootEpic;

Я бы хотел избежать испытания мрамора, что мне делать, чтобы сделать эту работу?


EDIT:

это мое определение шпиона.

    jest.mock('services/moviesService');

    const spy = jest.spyOn(moviesService, 'searchMovies');

    beforeEach(() => {
        moviesService.searchMovies.mockImplementation(keyword => {
            return Promise.resolve(moviesResult);
        });
        spy.mockClear();
    });

так что в принципе эта вещь не должна называться, потому что время отката составляет 300 мс, и я пытаюсь проверить шпиона через 200 мс. Но через 10 мс вызывается шпион.

...