liveBook · Manning

Vitest

As explained in React in Depth

Vitest is a JavaScript testing framework with built-in support for test execution, assertions, mocking, and related testing features.

Vitest runs tests in a Vite-based React project. Its API is almost identical to Jest’s, but it does not come bundled with Vite. Pair it with React Testing Library to test components through their rendered behavior rather than using the runner alone. section 10.0 section 10.1.1

To add component tests to a standard Vite setup:

  • Install vitest and jsdom as development dependencies, alongside @testing-library/react and @testing-library/jest-dom. section 10.1.1
  • Mark *.test.js and *.test.jsx files as a Vitest environment in ESLint so globals such as test and expect are recognized. section 10.1.1
  • Set Vite’s test options to use globals and the jsdom environment, then add a package script invoking vitest. section 10.1.1
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  test: { globals: true, environment: "jsdom" },     #1
});

The Vite configuration supplies the test globals and simulated DOM needed by these component tests. section 10.1.1

Keep a component’s test beside it, such as MenuItem.test.jsx beside MenuItem.jsx. Arrange the render, act when interaction is needed, and assert the result. Test files run when tests are requested; they are ignored by the development run and production build. section 10.1 section 10.4

Listing 10.1 Unit-testing MenuItem
import {    #1
  render,    #1
  screen,   #1
  getByRole,  #1  
} from "@testing-library/react";   #1
import "@testing-library/jest-dom";    #2
import MenuItem from "./MenuItem";     #3
test(    #4
  "MenuItem renders a link in a list item",   #4
  () => {   #4
  // ARRANGE
  render(<MenuItem href="/blog" label="Blog" />);    #5
  // ASSERT
  const listItem = screen.getByRole("listitem");  #6
  const link = getByRole(listItem, "link");    #6
  expect(link).toHaveAttribute("href", "/blog");     #7
  expect(link).toHaveAttribute("title", "Blog");   #7
  expect(link).toHaveTextContent("Blog");   #7
});

The static-component test renders a menu item, finds its list item and link by role, then checks the link’s href, title, and text. section 10.1

For callbacks, vi.fn() creates a mock function whose invocation can be checked. In an interactive to-do test, a user click on the second item’s delete button must call the mock with that item. This verifies the callback contract without needing a real deletion handler. section 10.2.2

Listing 10.9 Testing the items component from a Todo app
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import "@testing-library/jest-dom";
import { vi } from "vitest";
import { Items } from "./Items";
test("Items should call onDelete callback 
when item is deleted", async () => {
  // ARRANGE
  const items = ["Item A", "Item B"];
  const mockDelete = vi.fn();    #1
  render(     #2
    <Items items={items} onDelete={mockDelete} />,    #2
  );    
  // ACT
  const user = userEvent.setup();
  const secondItemDelete = screen.getByRole("button", {
    name: "Delete 'Item B'",
  });
  await user.click(secondItemDelete);     #3

  // ASSERT
  expect(mockDelete)    #4
    .toHaveBeenCalledWith("Item B");  #4 
});

The test combines vi.fn(), a user-event click, and toHaveBeenCalledWith to check the delete callback’s argument. section 10.2.2

The default test run watches for file changes; use vitest run for a single run. Vitest also supports Istanbul coverage after additional configuration, producing a terminal summary and an HTML report. Use line and branch coverage to spot gaps, not as a blanket demand for 100%. section 10.1.1 section 13.1.2

How React in Depth covers it

How deep it goes
Works through setup, component assertions, callback mocks, and coverage configuration, but leaves Istanbul’s internals unexplained.
Examples
Tests a static menu link and a to-do delete callback, then inspects coverage for a function’s branches.
What it assumes
Assumes React components and a Vite project, while teaching the missing test infrastructure from installation onward.
What you can do after
Operate/configure it to run React component tests, verify mocked callbacks, and review coverage reports.
How it connects
Connects Vite, Jest, jsdom, React Testing Library, mock functions, and Istanbul coverage.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of React in Depth. The section links point to the parts of the book it draws on.