我试图测试表单提交。这是我的表单的样子。
const AccountForm = () => {
const account = useAccount(null);
const accountName = useInput("");
const accountAmount = useInput(0);
const [isLoading, setIsLoading] = useState(false);
const onSubmit = async (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();
setIsLoading(true);
try {
const acc: IAccount = {
id: String(Date.now()),
name: String(accountName.value),
amount: Number(accountAmount.value),
date: new Date().toLocaleDateString(),
};
await account.add(acc);
} catch (error) {
console.error(error);
}
setIsLoading(false);
};
return (
<div data-testid="account-form-wrapper">
<h2>Create new account</h2>
<div>
<form onSubmit={onSubmit}>
<fieldset disabled={isLoading}>
<label htmlFor="name">Name</label>
<input
type="text"
name="name"
id="name"
autoComplete="off"
value={accountName.value}
onChange={accountName.onChange}
/>
</fieldset>
<fieldset disabled={isLoading}>
<label htmlFor="amount">Amount</label>
<input
type="number"
name="amount"
id="amount"
value={accountAmount.value}
onChange={accountAmount.onChange}
/>
</fieldset>
<button
type="submit"
data-testid="submit-button"
disabled={isLoading}
>
Create Account
</button>
</form>
</div>
</div>
);
};
表单本身非常简单。它使用名为 useAccount
的自定义钩子返回 { value, add, set, edit }
。 Returns 中的方法使 api 调用 firebase。我想知道如何使用 React 测试库测试(模拟)account.add
。
这是我尝试过的:我尝试像这样模拟 const mockAdd = jest.fn(hookWrapper.result.current.add);
。但它不会被调用!
import {
toBeInTheDocument,
toBeDisabled,
toBeEnabled,
} from "@testing-library/jest-dom";
import { renderHook } from "@testing-library/react-hooks";
import { fireEvent, render, waitFor, act } from "@testing-library/react";
import AccountForm from "./form";
import useAccount from "../../hooks/useAccounts";
describe("./form.tsx", () => {
test("renders <AccountForm />", async () => {
const component = render(<AccountForm />);
const hookWrapper = renderHook(useAccount);
const submitBtn = component.getByText(/create account/i);
const accountNameInput = component.getByLabelText(/name/i);
const amountInput = component.getByLabelText(/amount/i);
fireEvent.change(accountNameInput, { target: { value: "bank" } });
fireEvent.change(amountInput, { target: { value: 200 } });
expect(submitBtn).toBeInTheDocument();
expect(submitBtn).toBeEnabled();
const mockAdd = jest.fn(hookWrapper.result.current.add);
waitFor(() => fireEvent.click(submitBtn));
expect(mockAdd).toHaveBeenCalledTimes(1);
expect(submitBtn).toBeDisabled();
});
});
这是我的代码覆盖率的样子:
第 24 行是 catch 块,第 26 行是 setIsLoading。