it('text field', async () => {
const props = {
openConfirmationModal: jest.fn()
}
const { queryByTestId, findByTestId } = render(
<FormInputs
openConfirmationModal={props.openConfirmationModal}
/>
);
const input = queryByTestId('input-component-amount') as HTMLInputElement;
expect(input).toBeInTheDocument();
fireEvent.change(input, { target: { value: 123 } });
const textArea = queryByTestId('textarea-component-textfield') as HTMLTextAreaElement;
expect(textArea).toBeInTheDocument();
fireEvent.change(textArea, { target: { value: 'This is some text!' } });
const submitButton = queryByTestId('button') as HTMLButtonElement;
expect(submitButton).toBeInTheDocument();
expect(submitButton).toBeEnabled();
fireEvent.click(submitButton);
expect(props.openConfirmationModal).toHaveBeenCalledTimes(1);
const submitModalButton = queryByTestId('confirmation-modal-submit-button') as HTMLButtonElement;
expect(submitModalButton).toBeInTheDocument();
});
import React, { useState } from 'react';
interface FormInputsProps {
openConfirmationModal: () => void;
}
const FormInputs: React.FC<FormInputsProps> = ({ openConfirmationModal }) => {
const [amount, setAmount] = useState<string>('');
const [reason, setReason] = useState<string>('');
const [isModalOpen, setIsModalOpen] = useState<boolean>(false);
const handleSubmit = () => {
if (amount && reason) {
openConfirmationModal();
setIsModalOpen(true);
}
};
const handleModalSubmit = () => {
Calling API....
setIsModalOpen(false); // Close modal on confirmation
};
return (
<div>
<input
data-testid="input-component-amount"
type="number"
value={amount}
onChange={(e) => setAmount(e.target.value)}
/>
<textarea
data-testid="textarea-component-textfield"
value={reason}
onChange={(e) => setReason(e.target.value)}
/>
<button
data-testid="button"
onClick={handleSubmit}
disabled={!amount || !reason}
>
Submit
</button>
{isModalOpen && (
<div data-testid="confirmation-modal">
<p>Are you sure you want to submit?</p>
<button
data-testid="confirmation-modal-submit-button"
onClick={handleModalSubmit}
>
Confirm
</button>
</div>
)}
</div>
);
};
export default FormInputs;
在
expect(props.openConfirmationModal).toHaveBeenCalledTimes(1)
无法看到模态并出现错误“无法找到元素”对于const submitModalButton = queryByTestId('confirmation-modal-submit-button') as HTMLButtonElement
。
我看到两个问题,fireEvent 和 queryByTestId。 您可以直接使用 findBy 或 getBy 来查找元素,而不是使用 queryByTestId 来查找元素。在异步使用的情况下,findBy 是首选。
问题在于 fireEvent,没有 act 块。 我建议使用反应测试库中的 userEvent 和 act 块。
userEvent 文档 请参考正确的版本,因为最新版本几乎没有变化。
await act(async () => {
await userEvent.type(textArea, "This is some text!");
}
await act(async () => {
await userEvent.click(submitButton);
});
这是一直以来的首选。 但无论如何,如果您希望继续执行 fireEvent,则始终需要将其包装在 act 块中。
await act(async () => {
fireEvent.change(textArea, { target: { value: 'This is some text!' } });
}
await act(async () => {
fireEvent.click(submitButton);
});
使用 fireEvent 时,通常异步状态不会正确传播,除非它被包装在 act 中