Как дождаться повторного увлажнения Redux Persist до окончания теста

У меня есть следующий код:

const App = () => {
    return (
        <Provider store={store}>
            <PersistGate persistor={persistor} loading={<Text>Loading!</Text>}>
                <ConnectedRootComponent />
            </PersistGate>
        </Provider>
    );
};

export default App;

который использует redux-persist для регидратации состояния, и, прежде чем это будет завершено, он покажет, что находится в свойстве загрузки. У меня есть Jest тест (только по умолчанию, который поставляется с реагировать родной из коробки):

it('renders without crashing', () => {
  const rendered = renderer.create(<App />).toJSON();
  console.log("Rendering: " + JSON.stringify(rendered));
  expect(rendered).toBeTruthy();
});

но хотя тест проходит, я вижу, что действия, которые persist/PERSIST а также persist/REHYDRATE все еще происходят, и значение, напечатанное на консоли в тесте (визуализированный вывод):

{
    "type": "Text",
    "props": {
        "accessible": true,
        "allowFontScaling": true,
        "ellipsizeMode": "tail"
    },
    "children": ["Loading!"]
}

Что я хочу сделать, так это подождать, пока redux-persist завершит увлажнение, а затем проверить полученное значение. Как я могу это сделать?

4 ответа

import React from 'react';
import App, {persistor} from '../App';

import renderer from 'react-test-renderer';

it('renders without crashing', (done) => {
  const appRendered = renderer.create(<App />);
  persistor.subscribe(function(){
      const rendered = appRendered.toJSON();
      console.log("Rendering: " + JSON.stringify(rendered));
      expect(rendered).toBeTruthy();
      done();
  });
});

вам просто нужно export persistor из файла приложения, а затем используйте приведенный выше код для проверки. работает отлично, я проверял.

Вы можете заметить, что persistor объект может подписаться с помощью обратного вызова, который выполняется, когда хранилище с избыточностью перекомпилировано.

Вы могли бы издеваться PersistGate всегда возвращаться props.children, тогда ваш тест может проверить отображаемое значение.

Вот как создать макет:

jest.mock('redux-persist/integration/react', () => ({
  PersistGate: props => props.children,
}))

Кредиты

Вы можете игнорировать persist во время тестирования с помощью

      jest.mock('redux-persist/integration/react', () => ({
  PersistGate: props => props.children,
}))
jest.mock('redux-persist', () => ({
  ...jest.requireActual('redux-persist'),
  persistReducer: jest.fn().mockImplementation((config, reducer) => reducer),
}));

Другие решения работают для меня, но вот что я в итоге использовал.

TL;DR

В вашей<PersistGate />добавьте загрузочный компонент и дождитесь его удаления в ваших тестах

      await waitForElementToBeRemoved(() => screen.getByText('Loading...'));

Полное объяснение

Итак, в моем коде у меня есть<Text />компонент, который будет отображаться во время увлажнения redux-persist

      <StoreProvider store={setupStore()}>
  <PersistGate loading={<Text>Loading...</Text>} persistor={persistor}>
    {children}
  </PersistGate>
</StoreProvider>

теперь в моем наборе тестов он будет ждать удаления компонента, прежде чем продолжить

      it('should render correctly', async () => {
  render(<App />);

  await waitForElementToBeRemoved(() => screen.getByText('Loading...'));

  const headline = screen.getByText("Welcome to the App!");
  expect(headline).toBeTruthy();
});
Другие вопросы по тегам