Как установить состояние функционального компонента react с помощью jest

#javascript #reactjs #redux #jestjs #use-state

#javascript #reactjs #redux #jestjs #использовать-состояние

Вопрос:

У меня есть компонент, который имеет форму и модальный. При нажатии кнопки submit появляется модальное окно и при подтверждении отправляется вызов серверной части.

Изначально модальное скрыто с помощью состояния (displayModal).

Я пытаюсь протестировать вызов API, найдя кнопку внутри модального отображения. Но не могу найти его, поскольку его нет в DOM (режим отображения равен false).

Как я могу установить состояние в jest test.

 const MyTypeComponent: FunctionComponent<MyType> = ({
props1,
props2,
ownProp1,
ownProp2
}) => {
  //There are two use effects to do something
  //set the modal state
  const [displayModal, setdisplayModalOpen] = useState(false);
  const updateStatusquantityService = () => {
    //Call an API
  };
  const InventoryStatusquantityFormSubmitted = (form) => {
    if (!form.isValid) {
      return;
    }
    //If form valid, display the modal;
  
  };
  return (
    <>
          <Modal
            isOpen={displayModal}
            setIsOpen={setdisplayModalOpen}
            id={"InventoryStatusTypeModal"}
          >
           //Usual Modal stuff and then button
            <Button id={"statusquantityUpdateBtn"} variant="primary" label="Update" onClick={() => updateStatusquantityService()}/>
          </Modal>
          <Form>
             //On form submit, call InventoryStatusquantityFormSubmitted() and display the modal
          </Form>
    </>
  );
};
export default connect(
  (state: RootState) => ({
   //map states to props
  }),
  (dispatch: ThunkDispatch) => ({
    //map props 1 and props 2
  })
)(InventoryStatusquantity);
  

Когда я пытаюсь вызвать щелчок даже по модальной кнопке ‘ statusquantityUpdateBtn ‘, найдя ее, как показано ниже, я получаю пустое значение, поскольку modal не отображается из-за его значения.

 it('Should submit status types form11', () => {
    const submitButtonOnModal = wrapper.find('#statusquantityUpdateBtn').
});
  

Я пытаюсь обновить состояние с помощью

 wrapper.instance().setdisplayModalOpen(true)
  

Но получение ошибки wrapper.instance().setdisplayModalOpen не является функцией.

Я монтирую с помощью простой команды mount:

 export const mountWithMemoryRouter = (element: JSX.Element) => {
    return mount(<MemoryRouter>{element}</MemoryRouter>);
};
 
wrapper = mountWithMemoryRouter(
    <Theme>
        <Provider store={store}>
            <MyTypeComponent
                {...defaultProps}
                ownProp1={null}
                ownProp2={null}
            />
        </Provider>
    </Theme>
);
 
  

Ответ №1:

Эти перехватчики состояний ограничены функцией, поэтому ничто за пределами функции не может получить к ним доступ. Вот почему вы получаете ошибки «это не функция». Это похоже на

 function x() {
   const y = 0
}

x().y // Error
  

Я не вижу в вашем коде ничего, что вызывается setdisplayModalOpen(true) для отображения модального.

Предполагая, что вы предоставили только частичный код (но что он написан на вашем компьютере), и есть какая-то кнопка или что-то, что запускается setdisplaymodalOpen(true) (я предполагаю, что есть кнопка отправки формы), тогда, если бы мне нужно было это протестировать, я бы вместо этого использовал библиотеку тестирования React и имел что-то вроде

 import { render, screen, fireEvent, waitFor } from 'react-testing-library'
import MyComponent from './components/one-to-test'

test('does whatever', async () => {
  render(<MyComponent/>)
  const showModalBtn = screen.getByText('Text of Button You Click to Display Modal')
  fireEvent.click(showModalBtn)
  await waitFor(() => expect(screen.getByText('Update')).not.toBeNull())
  // You are now assured the modal is visible and can continue with the rest of your test
})
  

В этом тесте вы сначала инструктируете библиотеку тестирования React для рендеринга компонента, который может отображать / скрывать модальный (т. Е. Форму). (Предполагая, что есть кнопка, которую вы нажимаете, чтобы отобразить модальную), вы получаете эту кнопку, а затем имитируете нажатие этой кнопки, и затем ваш тест ожидает, пока модальная функция не станет видимой (в этом случае он ожидает, пока не будет видна кнопка «Обновить», содержащаяся в модальной функции).).

Затем вы можете продолжить тестирование своего модального (например, нажать кнопку Обновления другим fireEvent.click(updateBtn) .

Если вы хотите создать макет своего API, вы также можете добавить

 jest.mock('./my/api/library', () => ({
  whateverApiCall: jest.fn(() => whateverItShouldReturn)
})
  

Теперь, когда вы нажимаете кнопку отправки формы, она вызовет вашу издевательскую функцию API, которая возвращает все, что вы определили для возврата, и, предполагая, что она не выдает / отклоняет, ваш модал отобразится, и вы продолжите, как описано выше.