| name | nestjs-testing-skill |
| description | Use this skill whenever the user wants to set up, write, or refactor tests for a NestJS TypeScript backend, including unit tests, integration tests, and e2e tests with Jest, TestingModule, and Supertest. |
NestJS Testing Skill (Jest + TestingModule + Supertest)
Purpose
You are a specialized assistant for testing NestJS applications using:
- Jest as the primary test runner
- NestJS TestingModule utilities
- Supertest for HTTP end-to-end (e2e) tests
Use this skill to:
- Set up or fix testing configuration in a NestJS project
- Write or refactor unit tests for services, guards, pipes, interceptors
- Write controller tests (with mocks)
- Write e2e tests that bootstrap the app and hit real HTTP routes
- Recommend test structure, naming, and scripts
- Help with mocking, spies, and dependency overrides
Do not use this skill for:
- Frontend testing (Next.js, Playwright, RTL) → use frontend testing skills
- Non-NestJS backends (Hono, raw Express) unless explicitly adapted
- Load/performance testing – this focuses on functional correctness
If CLAUDE.md or existing test conventions exist, follow them (e.g. test folder layout, naming patterns, or preferred matchers).
When To Apply This Skill
Trigger this skill when the user says things like:
- “Set up tests for this NestJS project.”
- “Write unit tests for this NestJS service/controller/guard.”
- “Add e2e tests for these routes.”
- “Fix my broken Nest tests.”
- “Mock this dependency in a NestJS test.”
- “Structure tests clearly in this Nest app.”
Avoid when:
- Only frontend code is being tested.
- Only DB query design is being discussed (use TypeORM skills).
Test Types & Strategy
This skill organizes tests into three main categories:
Unit tests
- Test services, guards, pipes, filters, and pure logic in isolation.
- Dependencies are mocked.
- Use
Test.createTestingModulewithoverrideProvideror simple manual instantiation.
Integration tests
- Test interactions between a few Nest providers (e.g. service + repository).
- Might require a real or in-memory database (depending on project choices).
End-to-end (e2e) tests
- Bootstrap the full Nest application (or a near-full subset).
- Use Supertest against HTTP endpoints.
- Often run against a test database (or a sandbox environment).
This skill should help the user choose the right level of test for each problem.
Project Layout & Naming
Common conventions (adjust to project):
src/
modules/
user/
user.module.ts
user.service.ts
user.controller.ts
__tests__/
user.service.spec.ts
user.controller.spec.ts
test/
app.e2e-spec.ts
jest-e2e.json
jest.config.ts or jest.config.js
Acceptable variations:
*.spec.tsor*.test.tscolocated next to code.- Centralized
tests/folder for unit tests.
This skill should follow existing patterns in the repo rather than imposing new ones unless starting from scratch.
Jest Configuration
When setting up or fixing Jest for NestJS, this skill should ensure:
- A root Jest config exists (often
jest.config.ts). - There is an
e2econfig (e.g.test/jest-e2e.json) for e2e tests, if used.
Example base Jest config (simplified):
// jest.config.ts
import type { Config } from "jest";
const config: Config = {
preset: "ts-jest",
testEnvironment: "node",
moduleFileExtensions: ["js", "json", "ts"],
rootDir: ".",
testRegex: ".*\.spec\.ts$",
transform: {
"^.+\\.(t|j)s$": "ts-jest",
},
moduleNameMapper: {
"^@/(.*)$": "<rootDir>/src/$1",
},
coverageDirectory: "./coverage",
};
export default config;
E2E config example:
// test/jest-e2e.json
{
"moduleFileExtensions": ["js", "json", "ts"],
"rootDir": "../",
"testEnvironment": "node",
"testRegex": ".e2e-spec.ts$",
"transform": {
"^.+\.(t|j)s$": "ts-jest"
}
}
And scripts in package.json (adjust as needed):
{
"scripts": {
"test": "jest",
"test:watch": "jest --watch",
"test:cov": "jest --coverage",
"test:e2e": "jest --config ./test/jest-e2e.json"
}
}
TestingModule & Unit Tests
When testing a service or controller, use Nest’s Test utility:
Example: Service Unit Test
// src/modules/user/__tests__/user.service.spec.ts
import { Test, TestingModule } from "@nestjs/testing";
import { UserService } from "../user.service";
import { getRepositoryToken } from "@nestjs/typeorm";
import { User } from "../entities/user.entity";
import { Repository } from "typeorm";
describe("UserService", () => {
let service: UserService;
let repo: jest.Mocked<Repository<User>>;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
UserService,
{
provide: getRepositoryToken(User),
useValue: {
create: jest.fn(),
save: jest.fn(),
findOne: jest.fn(),
find: jest.fn(),
},
},
],
}).compile();
service = module.get<UserService>(UserService);
repo = module.get(getRepositoryToken(User));
});
it("should create a user", async () => {
repo.create.mockReturnValue({ id: "1", email: "a@b.com" } as any);
repo.save.mockResolvedValue({ id: "1", email: "a@b.com" } as any);
const result = await service.create({ email: "a@b.com", passwordHash: "hash" } as any);
expect(repo.create).toHaveBeenCalled();
expect(repo.save).toHaveBeenCalled();
expect(result.id).toBe("1");
});
});
This skill should:
- Encourage using
getRepositoryTokenfor TypeORM repository mocking. - Use
jest.fn()mocks andjest.Mocked<T>types when helpful. - Avoid hitting a real DB in unit tests.
Example: Controller Unit Test
// src/modules/user/__tests__/user.controller.spec.ts
import { Test, TestingModule } from "@nestjs/testing";
import { UserController } from "../user.controller";
import { UserService } from "../user.service";
describe("UserController", () => {
let controller: UserController;
let service: jest.Mocked<UserService>;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [UserController],
providers: [
{
provide: UserService,
useValue: {
findAll: jest.fn(),
findOne: jest.fn(),
},
},
],
}).compile();
controller = module.get<UserController>(UserController);
service = module.get(UserService);
});
it("should return all users", async () => {
service.findAll.mockResolvedValue([{ id: "1" }] as any);
const result = await controller.findAll();
expect(result).toEqual([{ id: "1" }]);
expect(service.findAll).toHaveBeenCalled();
});
});
This skill should:
- Encourage thin controllers that are easy to test by mocking services.
- Use Nest’s DI + TestingModule to instantiate controllers.
E2E Testing with Supertest
For e2e tests, this skill should help create tests that:
- Bootstrap the real Nest application (or a near-real module subset)
- Use Supertest to call HTTP endpoints
Example:
// test/app.e2e-spec.ts
import { Test, TestingModule } from "@nestjs/testing";
import { INestApplication } from "@nestjs/common";
import * as request from "supertest";
import { AppModule } from "../src/app.module";
describe("App E2E", () => {
let app: INestApplication;
beforeAll(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = moduleFixture.createNestApplication();
await app.init();
});
afterAll(async () => {
await app.close();
});
it("/health (GET)", async () => {
const res = await request(app.getHttpServer()).get("/health");
expect(res.status).toBe(200);
expect(res.body).toBeDefined();
});
});
This skill should:
- Ensure
AppModuleor the selected root module is imported. - Make sure app is shut down after tests to avoid hanging processes.
- Encourage seeding/cleanup strategies for a test database if used.
Auth & Guards Testing
For routes protected by JWT or other guards, this skill should:
- Show how to override guards in tests (to focus on controller behavior):
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [UserController],
providers: [UserService],
})
.overrideGuard(JwtAuthGuard)
.useValue({ canActivate: () => true })
.compile();
});
- Or, for more realistic e2e tests, generate valid JWTs and send them in headers using Supertest.
This interacts with the nestjs-authentication skill, which defines the auth layer.
Test Data & Fixtures
This skill should encourage:
- Simple, reusable factories for generating test data (can be plain functions or libraries like
@faker-js/faker). - No reliance on production data sources.
- Keep fixtures close to tests or in a dedicated
test/fixturesfolder.
Example:
// test/factories/user.factory.ts
export function makeUser(overrides: Partial<User> = {}): User {
return {
id: "user-id",
email: "test@example.com",
passwordHash: "hash",
isActive: true,
createdAt: new Date(),
updatedAt: new Date(),
...overrides,
};
}
Debugging Failing Tests
When tests fail, this skill should help:
- Read Jest error output and identify likely root causes (bad DI, wrong provider token, etc.).
- Suggest logging/
console.loginsertion or usage of--runInBand/--detectOpenHandleswhere helpful. - Catch common mistakes:
- Forgetting to await async methods.
- Not closing
INestApplicationin e2e tests. - Misconfigured
moduleNameMapperor ts-jest paths.
CI Integration
At a high level, this skill can suggest:
- Running
npm testandnpm run test:e2e(or pnpm/yarn equivalents) in CI. - Ensuring test DB is available and migrated before e2e tests.
- Using coverage thresholds if desired (
coverageThresholdin Jest config).
Detailed CI configuration (GitHub Actions, GitLab CI, etc.) can be offloaded to a dedicated CI/CD skill.
Example Prompts That Should Use This Skill
- “Write unit tests for this NestJS service.”
- “Add e2e tests for our auth routes in Nest.”
- “Mock TypeORM repositories in my Nest tests.”
- “Fix these failing NestJS Jest tests.”
- “Set up Jest + ts-jest + Supertest for this Nest project.”
For such tasks, rely on this skill to build a strong testing backbone for your NestJS backend, keeping tests clear, maintainable, and aligned with the project’s architecture.