Дублирующиеся действия в наблюдаемом редуксе потоке при использовании с 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
Или же:
const store = mockStore();
store2 = mockStore();
mockStore();
mockStore();
mockStore();
store.dispatch({ type: 'FOO' }); // -> Observable get 5 FOO actions
... и так далее...
Я ожидаю, так как я использую replaceEpic и mockStore, и я использую разные jest-тесты, что один тест не должен влиять на другой, и один mockStore не должен влиять на другой.
Поэтому я ожидаю, что даже если у меня будет несколько тестов, каждый из которых вызывает mockStore(), мои эпики получат правильный поток действий.
Открытые вопросы:
1 ответ
В настоящее время в соответствии с наблюдаемой избыточностью предполагается, что функция промежуточного программного обеспечения, возвращаемая createEpicMiddleware()
не будет вызываться несколько раз. redux-mock-store вызывает его каждый раз, когда вы вызываете mockStore. Хотя такое поведение, вероятно, официально не задокументировано, моя интуиция говорит мне, что наблюдаемая избыточность не должна делать этого предположения. Подобные библиотеки, как, например, 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