I am having trouble passing a button click test in my app component using Vitest, react-testing-library and jest dom. I am new to unit testing and I can't seem to figure out how to get my test for the submit button in my form working. (Add Button)
I get AssertionError: expected "spy" to be called 1 times, but got 0 times
Here is my TaskForm component
import { useDispatch } from "react-redux";
import { add } from "./taskFormSlice";
import { useRef, useState } from "react";
import Tasks from "./Tasks";
const TaskForm = () => {
const dispatch = useDispatch();
const task = useRef<string>("");
// local state to reset input field after submitting form
const [userInputVal, setUserInputVal] = useState("");
return (
<div className="flex flex-col space-y-8 items-center justify-center min-h-screen bg-indigo-900">
<div className="text-7xl text-white mt-10">To Do App</div>
<div className="flex flex-row space-y-4 items-center justify-center">
<form onSubmit={(e) => e.preventDefault()}>
<input
value={userInputVal}
onChange={(e) => {
setUserInputVal(e.target.value);
task.current = e.target.value;
}}
className=" w-96 border-solid border-sky-500 rounded-full border-2 px-8 py-2 placeholder:text-center text-md"
placeholder="Enter Task"
/>
<div className="inline-block">
<button
className="px-4 py-2 bg-blue-700 rounded-full text-white shadow-lg hover:shadow-sky-700 ml-40 mt-2 sm:ml-2"
type="submit"
onClick={() => {
setUserInputVal(" ");
dispatch(add(task.current));
}}
>
Add
</button>
</div>
</form>
</div>
<Tasks></Tasks>
</div>
);
};
export default TaskForm;
Here is my the part of my test file containing the unit test for the add/submit button. It does not seem like the right way to mock the button click by passing it into the component but I am not sure how else do I mock the button click function so that I can test the button will be clicked.
import { describe, expect, test, vi } from "vitest";
import { fireEvent, screen, waitFor } from "@testing-library/react";
import TaskForm from "./TaskForm";
// Unit Test on React components
// Unit test to test that input box takes in a input
describe.sequential("to do list components render correctly", () => {
test("input box takes in user input", async () => {
renderWithProviders(<TaskForm></TaskForm>);
const input = screen.getByPlaceholderText("Enter Task");
fireEvent.change(input, { target: { value: "test todo" } });
await waitFor(() => {
expect(input).toHaveValue("test todo");
});
});
test("Test button click to ensure that it works", () => {
const handleClick = vi.fn();
renderWithProviders(<TaskForm onClick={handleClick}></TaskForm>);
fireEvent.click(screen.getByText("Add"));
expect(handleClick).toHaveBeenCalledTimes(1);
});
});