Nfs testing patterns
Skill juncoding/nextjs-fullstack-starter/skills/nfs-testing-patterns
Claude Code plugin: scaffold and maintain lightweight back-office apps on pure Next.js (App Router) — Server Components for reads, Server Actions for writes, services in src/server/modules/. No tRPC.
npx -y skills add juncoding/nextjs-fullstack-starter --skill nfs-testing-patternsAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Test-writing patterns for projects scaffolded with nextjs-fullstack-starter. Use whenever the user is writing or reviewing tests in such a project, asks 'how do I test X', wants to add test coverage for a new module, or needs to debug a failing test. Covers service-layer unit tests (the high-value layer where most coverage lives), integration tests with a real Postgres (Testcontainers), Server Action tests via direct invocation, route-handler tests, and Playwright e2e. Each section explains WHAT to test at that layer and HOW so test effort lands where it pays off.
SKILL.md
3.9 KB, as published. Nobody here has run it
Testing patterns for the fullstack stack
For projects scaffolded with nextjs-fullstack-starter. Tests are first-class — the verification gate (pnpm verify) runs them on every PR.
Use this skill when
- Writing tests for a new service, action, or route handler.
- Adding coverage to existing code.
- Debugging a failing test.
- Deciding what to test at which layer.
- Reviewing a PR's test coverage.
The shape of testing in this stack
The architecture has four delivery shapes — Server Components, Server Actions, route handlers, MCP tools — all calling services. Most of your testing effort goes into the service layer. Delivery wrappers are thin enough that integration tests cover them implicitly.
Roughly:
| Layer | Test type | Why |
|---|---|---|
| Service | Unit tests with mocked Prisma | Where the business logic lives. Highest leverage. |
| Service (occasional) | Integration tests against real Postgres | When Prisma's query builder behaviors matter — joins, transactions, indexes. |
| Server Action | Direct invocation tests OR e2e | Thin wrapper — usually covered by e2e. Unit-test only when the action does non-trivial parsing. |
| Route handler | Direct invocation tests | Same as actions — thin. Test webhook signature verification and edge cases. |
| Page / UI | Playwright e2e | Server Components are server-rendered HTML; integration testing them is e2e. |
| MCP tool | Same as routes/actions — thin wrapper test | Verifies the tool registry contract; service logic is covered by service tests. |
Reference index
Read the file matching what you're testing:
| Testing this | Read this |
|---|---|
| A service method | references/service-tests.md |
| A Server Action | references/server-action-tests.md |
| A route handler / webhook | references/route-handler-tests.md |
| A page or user flow end-to-end | references/e2e-playwright.md |
Quick rules
- Mock at the boundary, not the layer above. When unit-testing a service, mock
@/server/db/clientand@/server/auth/permissions. Don't mock other services it calls — let those use their real (also-mocked-Prisma) implementations. - Test inputs and outputs, not internals. Don't assert on what private helpers got called. Assert on what came back and what the DB was asked to do.
- Use real
db.$transactionsemantics. When mocking Prisma, the$transactionmock should pass atxshaped like the same client. Otherwise audit-inside-transaction patterns appear broken in tests. - Permission denials get their own tests.
requirePermissionis critical — every service should have at least one test that confirms the denial path throws. - Don't test types. TypeScript runs ahead of every test; type-only invariants are already checked.
- Don't test the framework. No test for
requireSessionredirecting — that's Better Auth's job. Trust the upstream.
Running tests
pnpm test # one-shot
pnpm test:watch # watch mode
pnpm test -- customer # filter by name
pnpm test -- --updateSnapshot
The verification gate
pnpm verify
Chains format:check, tsc --noEmit, lint, build, test, db:diff. CI runs the same — the gate is canonical. If tests are flaky, that's a test bug, not a CI bug. Fix it; don't retry.