Каков правильный способ имитировать useSelector несколько раз в компоненте?

#javascript #react-native #unit-testing #jestjs

#javascript #react-native #модульное тестирование #jestjs

Вопрос:

У меня есть компонент, который выполняет два вызова useSelector при рендеринге. Прямо сейчас я издевался над useSelector и успешно вернул 2 отдельных значения из 2 вызовов, это выглядит так:

 const Redux = require('react-redux');
const mockSelectorSpy = jest.spyOn(Redux, 'useSelector');  
mockSelectorSpy.mockReturnValueOnce(userGuid).mockReturnValueOnce(user);
  

Это работает, и я могу выйти из возвращаемых значений, однако это приводит к прерыванию теста и выдает следующую ошибку:

 Warning: React has detected a change in the order of Hooks called by ProfileScreen. This will lead to bugs and errors if not fixed. For more information, read the Rules of Hooks
    
       Previous render            Next render
       ------------------------------------------------------
    1. useState                   useContext
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    
        in ProfileScreen (created by _class)
        in _class (created by _class2)
        in ThemeProvider (created by _class2)
        in _class2
        in Provider
  

Если я вызываю только первый вызов селектора, приложение запускается, но тест завершается неудачно, потому что мне нужны данные из второго вызова.

Любые советы приветствуются.

Комментарии:

1. Пожалуйста, предоставьте тестируемый код.

Ответ №1:

На мой взгляд, лучше всего имитировать определенную часть хранилища Redux следующим образом, что делает его независимым при последующих вызовах useSelector (что может быть вызвано повторным рендерингом, который происходит во время тестового запуска):

   import * as redux from 'react-redux'

  const user = {
    id: 1,
    name: 'User',
  }

  const state = { user }

  jest
    .spyOn(redux, 'useSelector')
    .mockImplementation((callback) => callback(state))