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...
You are a specialized assistant for testing NestJS applications using:
Use this skill to:
Do not use this skill for:
If CLAUDE.md or existing test conventions exist, follow them (e.g. test folder layout, naming patterns, or preferred matchers).
Trigger this skill when the user says things like:
Avoid when:
This skill organizes tests into three main categories:
Unit tests
Test.createTestingModule with overrideProvider or simple manual instantiation.Integration tests
End-to-end (e2e) tests
This skill should help the user choose the right level of test for each problem.
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.ts or *.test.ts colocated next to code.tests/ folder for unit tests.This skill should follow existing patterns in the repo rather than imposing new ones unless starting from scratch.
When setting up or fixing Jest for NestJS, this skill should ensure:
jest.config.ts).e2e config (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"
}
}
When testing a service or controller, use Nest’s Test utility:
// 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:
getRepositoryToken for TypeORM repository mocking.jest.fn() mocks and jest.Mocked<T> types when helpful.// 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:
For e2e tests, this skill should help create tests that:
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:
AppModule or the selected root module is imported.For routes protected by JWT or other guards, this skill should:
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [UserController],
providers: [UserService],
})
.overrideGuard(JwtAuthGuard)
.useValue({ canActivate: () => true })
.compile();
});
This interacts with the nestjs-authentication skill, which defines the auth layer.
This skill should encourage:
@faker-js/faker).test/fixtures folder.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,
};
}
When tests fail, this skill should help:
console.log insertion or usage of --runInBand/--detectOpenHandles where helpful.INestApplication in e2e tests.moduleNameMapper or ts-jest paths.At a high level, this skill can suggest:
npm test and npm run test:e2e (or pnpm/yarn equivalents) in CI.coverageThreshold in Jest config).Detailed CI configuration (GitHub Actions, GitLab CI, etc.) can be offloaded to a dedicated CI/CD skill.
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.