Повторяющиеся действия в наблюдаемом redux потоке при использовании с redux-mock-store

Я открыл вопрос, но на случай, если я что-то не так делаю:

При написании одного теста с использованием jest и redux-mock-store все работает, как ожидалось. Но если я использую mockStore несколько раз (в одном и том же тесте или даже в другом), то действия, отправленные в любом из созданных хранилищ, отправляются несколько раз в наблюдаемом (но только один раз в магазине, как store.getActions () состояния.

Репозиторий репродукции: https://framagit.org/jalil/redux-observable-mock-store-duplicate

tldr;

Это работает :

const store = mockStore();
store.dispatch({ type: 'FOO' }); // -> Observable get 1 FOO action

Это не так:

const store = mockStore();
store2 = mockStore();
mockStore();
store.dispatch({ type: 'FOO' }); // => Observable get 3 FOO actions

Or :

const store = mockStore();
store2 = mockStore();
mockStore();
mockStore();
mockStore();
store.dispatch({ type: 'FOO' }); // -> Observable get 5 FOO actions

... и так далее ...

Я ожидаю, что, поскольку я использую replaceEpic и mockStore, и я использую разные тесты jest, один тест не должен влиять на другой, а один mockStore не должен влиять на другой.

Итак, я ожидаю, что даже если у меня есть несколько тестов, каждый из которых вызывает mockStore (), мои эпики получат правильный поток действий.

Открытые выпуски:


person Jalil    schedule 31.12.2017    source источник


Ответы (1)


В настоящее время redux-observable предполагает, что функция промежуточного программного обеспечения, возвращаемая createEpicMiddleware(), не будет вызываться несколько раз. Кажется, что redux-mock-store вызывает его каждый раз, когда вы вызываете mockStore. Хотя это поведение, вероятно, официально не задокументировано, моя интуиция подсказывает мне, что redux-observable не должен делать этого предположения. Подобные библиотеки, такие как redux-saga, тоже использовались, но, возможно, они перестали работать, я не проверял.

Не сразу понятно, почему этого раньше никто не замечал. Я не вижу каких-либо заметных изменений ни в одной из библиотек, которые могли бы это сделать недавно. Я предполагаю, что у него не было заметных побочных эффектов, поэтому никто не заметил. например ваш пример не фильтрует никаких действий и не испускает их, вместо этого просто всегда регистрируется с помощью .do().

У меня сейчас отпуск, так что я не могу углубиться в это до конца этой недели. Извините! Но вы можете обойти это, создав новое epicMiddleware и вызывая configureMockStore для каждого теста вместо его повторного использования. Один из примеров может быть примерно таким:

const mockStore = (...args) => {
  const epicMiddleware = createEpicMiddleware(someEpic);
  const factory = configureMockStore([epicMiddleware]);
  return factory(...args);
};

Приспосабливайтесь к своим потребностям; например если нужно сменить рут эпик.

Мы будем отслеживать это в вашем тикете: https://github.com/redux-observable/redux-observable/issues/389

person jayphelps    schedule 31.12.2017
comment
Спасибо, @jayphelps! Это то, что я предполагал ... Я могу подтвердить, что если я воссоздаю configureMockStore и mockStore перед каждым тестом, он будет работать так, как ожидалось, поэтому в этом нет необходимости :-) - person Jalil; 01.01.2018
comment
Просто чтобы ответить на ваше лучшее предположение, я не думаю, что это почему никто не заметил ... Я хотел, чтобы мой пример воспроизведения был простым, чтобы он ничего не делал, но у меня это было в реальном проекте с эпосом реального мира. Думаю, никто этого не видел, потому что никто не тестирует эпики :-) Или, может быть, только с одним тестовым примером для каждого ... Или, может быть, с одним фиктивным магазином ... Или, может быть, каждый раз переопределяя createEpicMiddleware ... - person Jalil; 01.01.2018
comment
Продолжим обсуждение в github.com/redux-observable/redux-observable/issues/ 389 - person Jalil; 01.01.2018