Learn / Frameworks / Next.js / Testing Next.js Apps

Next.js · Lesson 13 of 15

Testing Next.js Apps

Unit-test server actions and cover critical flows with Playwright.

  • Advanced
  • 16 min read
  • 3 objectives

Before this lessonLesson 12: Config, Env and Route Segment Options

What you will learn

  • Test a server action
  • Write a Playwright spec
  • Mock fetch in tests

Your Progress

0 of 15 lessons 0%

  • Lessons0 / 15
  • Completed0
  • Est. time left~ 4 hours

Create a free account to keep your progress on every device.

Test server code with Vitest and user flows with Playwright. Mock the network; do not hit a real database in unit tests.

Unit-test a server action

import { describe, expect, it, vi } from "vitest";
import { createPost } from "./actions";

vi.mock("@/lib/db", () => ({ db: { post: { create: vi.fn() } } }));

it("rejects an empty title", async () => {
  const fd = new FormData();
  fd.set("title", "  ");
  const result = await createPost(fd);
  expect(result).toEqual({ error: "Title required" });
});

Playwright for a critical path

npm init playwright@latest
// e2e/home.spec.ts
import { test, expect } from "@playwright/test";

test("home has a heading", async ({ page }) => {
  await page.goto("/");
  await expect(page.getByRole("heading", { name: /welcome/i })).toBeVisible();
});

Run the app with a test database or MSW. Point Playwright at npm run dev locally and a preview URL in CI.

Mocking fetch in component tests

global.fetch = vi.fn().mockResolvedValue({
  ok: true,
  json: async () => [{ id: 1, title: "Hello" }],
});
Up next · Lesson 14Images, Fonts and Performancenext/image, next/font, bundle analysis and Core Web Vitals.