0

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);
  });
});

1 Answer 1

1

The problem with your test is that TaskForm doesn't except params. So you cannot provide an onClick function to spy on. I use jest, so the actual code may be a bit different, but I believe the principles are the same.

You could spy on dispatch and/or check if userInputVal has been set This is how I spy on dispatch:

const testStore = createStore();
const dispatchSpy = jest.spyOn(testStore, 'dispatch');
expect(dispatchSpy).toHaveBeenCalledWith('the task it is called with');

I don't see any sort of store in your tests. Maybe that is a Vitest thing, but I think you should have it, especially if you want to spy on dispatch.

You already check the value in Input in your other test, so you can probably do something similar for this one.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.