React-Redux button unit test in Vitest encounters failure

I'm struggling with passing a button click test in my app component using Vitest, react-testing-library, and jest dom. As a newcomer to unit testing, I'm having difficulty figuring out how to make my test for the submit button in my form function properly. (Add Button)

I keep getting an AssertionError: expected "spy" to be called 1 time, but it was called 0 times.

Below is the code for 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>("");
  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;

In my test file, I have a unit test for the add/submit button. I'm not sure if mocking the button click by passing it into the component is the correct approach. How else can I mock the button click function to properly test that the button will be clicked?

import { describe, expect, test, vi } from "vitest";
import { fireEvent, screen, waitFor } from "@testing-library/react";
import TaskForm from "./TaskForm";

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

Answer №1

Your test is facing an issue because TaskForm does not accept params, preventing you from providing an onClick function to spy on. I utilize jest for testing, so while the code may vary slightly, the fundamental concepts remain the same.

To spy on dispatch and/or verify if userInputVal has been set, you can follow this approach:

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

I noticed there is no mention of a store in your tests. It may be related to Vitest, but having a store is crucial, especially if you intend to spy on dispatch.

You are already checking the value in Input in another test, so a similar approach can likely be applied here as well.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Managing the handling of each catch in $httpBackend.when()

I've been working on creating Jasmine unit tests for my Angular project, and I've come across a situation that I'm not quite sure how to tackle. Within my project, I have implemented a response interceptor that can retry a request if it enc ...

Playfully teasing Django's database saving operation

I am currently attempting to mock a save method call on a django models.Model using Mock as my mocking library. The function I am testing is located in house_factory.py under apps.deps.house_factory. house_factory.py: from apps.market.models import H ...

Generate a versatile Union type featuring a mapped property

I am currently working with different types of data enum DataTypes { Email = 'email', Checkbox = 'checkbox', } type DataTypeValues = { [DataTypes.Email]: string; [DataTypes.Checkbox]: boolean; }; type Type1<T extends DataTy ...

Having difficulty navigating to a different page in Angular 4

I'm currently attempting to transition from a home page (localhost.com) to another page (localhost.com/listing). Although the app compiles correctly, I encounter an issue where nothing changes when I try to navigate to the new page. My approach has m ...

React-query v5 - Updating or fetching outdated query

I am currently using the Tanstack/react-query v5.12.2 library and I am facing an issue with invalidating or refetching an inactive query using the useQueryClient() function. It seems that something has changed in version 5 of the library. I have tried sett ...

Navigating in Angular is made easy with the Angular routing feature, which allows you to redirect

I have been working through the Angular Tour of Heroes Guide and encountered the section on the "default route". I decided to experiment by removing the pathMatch attribute from the Route associated with an empty string. Below is the code snippet in quest ...

Tips for executing Firebase transactions involving read operations subsequent to write operations

Is there a method to incorporate read operations following write operations in nodejs for cloud and background functions? According to the information provided in the documentation, only server client libraries allow transactions with read operations afte ...

The data type 'string[]' cannot be assigned to the data type 'listData[]'

I'm currently developing a flexible component that allows the list view to be utilized by different components. However, the challenge arises from the fact that each component has a different data format. In my project, I'm unable to use type any ...

Add a React component to the information window of Google Maps

I have successfully integrated multiple markers on a Google Map. Now, I am looking to add specific content for each marker. While coding everything in strings works fine, I encountered an issue when trying to load React elements inside those strings. For ...

Looping through NavItems component using JavaScript or Angular

My Angular project includes a navbar component with an app sidebar that has a navItems attribute. Below is the content of my navBar: <app-header style="background-color : #e65100;" [fixed]="true" [navbarBrandFull]="{ src: &a ...

ts:Accessing the state within a Redux store

In my rootReducer, I have a collection of normal reducers and slice reducers. To access the state inside these reducers, I am using the useSelector hook. Here is my store setup : const store = configureStore({reducer : rootReducer}); Main Reducer: const ...

Fix the TypeScript issue encountered during a CDK upgrade process

After upgrading to version 2.0 of CDK and running npm install, I encountered an issue with the code line Name: 'application-name'. const nonplclAppNames = configs['nonplclAppNames'].split(','); let nonplclAppNamesMatchingState ...

Tips for creating unit tests for methods in Angular components with jasmine

As a beginner in jasmine unit testing, I am struggling to understand how to write and implement tests in jasmine. I have been encountering numerous errors along the way. Is there anyone who can assist me with writing a unit test for the code snippet below ...

Merge information from two sources utilizing concatMap

I am encountering an issue where I need to extract a specific value from the data obtained from my first service in order to pass it on to the second service. Angular seems to have trouble with 'firstserviceResultsJson.indSsn'. How can I successf ...

Tips for leveraging the functions service in Next.js for better code reusability

I am just starting to learn Next.js and I have a preference for organizing my API functions in a separate folder called services. I attempted to implement some code based on this topic but unfortunately, it did not work as expected. It seems like my api fu ...

Webpack is having trouble identifying Node's process module

It has been more than ten years since I last worked with JavaScript, but recently I had an idea for an app that would be best implemented as a NodeJS app. As I delved into the modern JS ecosystem, like many others, I found myself thoroughly confused, haha. ...

Unlocking Not Exported Type Definitions in TypeScript

Take a look at this TypeScript code snippet: lib.ts interface Person { name: string; age: number; } export default class PersonFactory { getPerson(): Person { return { name: "Alice", age: 30, } } } ...

Enabling logging for the Mapnik SQL query while generating the map

Currently, I am utilizing the npm package known as Mapnik in conjunction with PostGIS. My goal is to include logging functionality that captures the SQL query executed by Mapnik, along with the value of the bbox parameter, when executing the render() funct ...

The type 'Text' does not have a property named 'then'

Transitioning from .js to typescript. When I changed the file extension from .js to .ts while keeping the same code, I encountered an error stating Property 'then' does not exist on type 'Text'.ts in the then((value) method. The return ...

Issue with TypeScript: Rxjs uses different syntax for setTimeout compared to what is defined in @types/node

System Information: Node version: v11.7.0 RxJS version: 6.3.3 @types/node version: 8.10.45 tsc version: 3.2.4 During the execution of tsc, it appears that there is an issue within Rxjs where the setTimeout function is being called without specifying th ...