Jest Redux Persist: TypeError: невозможно прочитать свойство 'catch' неопределенного значения в writeStagedState
Я пытаюсь протестировать свой LoginScreen с помощью Jest и Typescript. Я использую redux и redux-persist для хранения и настроил хранилище для использования AsyncStorage как части конфигурации. Я подозреваю, что redux-persist пытается регидратировать после того, как встроенная функция тайм-аута, которую он использует, исчерпывается, и пытается установить хранилище по умолчанию? Я получаю следующую ошибку:
console.error
redux-persist: rehydrate for "root" called after timeout. undefined
undefined
at _rehydrate (node_modules/redux-persist/lib/persistReducer.js:70:71)
at node_modules/redux-persist/lib/persistReducer.js:102:11
at tryCallOne (node_modules/promise/setimmediate/core.js:37:12)
at Immediate._onImmediate (node_modules/promise/setimmediate/core.js:123:15)
Сейчас мой тест выглядит так:
describe('Testing LoginScreen', () => {
it('should render correctly', async () => {
const { toJSON } = render(<MockedNavigator component={LoginScreen} />);
await act(async () => await flushMicrotasksQueue());
expect(toJSON()).toMatchSnapshot();
});
});
а мой MockNavigator выглядит так:
type MockedNavigatorProps = {
component: React.ComponentType<any>;
params?: {};
};
const Stack = createStackNavigator();
const MockedNavigator = (props: MockedNavigatorProps) => {
return (
<MockedStorage>
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name='MockedScreen'
component={props.component}
initialParams={props.params}
/>
</Stack.Navigator>
</NavigationContainer>
</MockedStorage>
);
};
export default MockedNavigator;
Вот как я создаю свое хранилище:
import 'react-native-gesture-handler';
import * as React from 'react';
import { Provider } from 'react-redux';
import { PersistGate } from 'redux-persist/integration/react';
import { store, persistor } from '../src/AppState/store';
type MockedStorageProps = {
children: any;
};
const MockedStorage = (props: MockedStorageProps) => {
return (
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
{props.children}
</PersistGate>
</Provider>
);
};
export default MockedStorage;
2 ответа
Я решил эту же ошибку, используя этот совет из проблемы на
redux-persist
репозиторий: https://github.com/rt2zz/redux-persist/issues/1243#issuecomment-692609748.
(Это также имело побочный эффект, заключающийся в предотвращении ошибок регистрации в тесте из
redux-logger
.)
jest.mock('redux-persist', () => {
const real = jest.requireActual('redux-persist');
return {
...real,
persistReducer: jest
.fn()
.mockImplementation((config, reducers) => reducers),
};
});
@алексбразиер:
По сути, он просто обходит redux-persist, возвращая редукторы напрямую, не оборачивая их в redux-persist.
Решение LordParsley мне не помогло. (вызвал тайм-аут тестов), но направил меня на правильный путь. Добавляю это в свойjest.setup.js
решил мою ошибку:
jest.mock('@react-native-async-storage/async-storage', () => {
return {
getItem: async (...args) => args,
setItem: async (...args) => args,
removeItem: async (...args) => args,
};
});
Решение пришло из этого обсуждения: https://github.com/react-native-async-storage/async-storage/issues/379, они также предлагают скопировать макеты, но у меня это не сработало.
ОБНОВЛЕНИЕ : коллеге не понравилось решение, и он предпочел это: чтобы вы издевались только над функцией, вызывающей ошибку, и оставляли все остальные ошибки, как в исходном макете, добавьте следующее в файл макета для асинхронного хранилища, а не jest.setup и обратитесь к нему в своемjest.config
:
import asyncStorageMock from '@react-native-async-storage/async-storage/jest/async-storage-mock';
const originalSetItemMock = asyncStorageMock.setItem.bind(asyncStorageMock);
asyncStorageMock.setItem = function newSetItemMock() {
// Types falsely assert that the below mock function returns a promise, so we ignore the return value.
originalSetItemMock(...arguments);
return Promise.resolve();
};
export default asyncStorageMock;