单元测试失败,因为 fest.fn() 未触发 openConfirmationModal 函数

问题描述 投票:0回答:1
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

javascript reactjs unit-testing jestjs automated-tests
1个回答
0
投票

我看到两个问题,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 中

© www.soinside.com 2019 - 2024. All rights reserved.