#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, которая возвращает все, что вы определили для возврата, и, предполагая, что она не выдает / отклоняет, ваш модал отобразится, и вы продолжите, как описано выше.