Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Nest Testing

ASecurity

NestJS testing patterns: Test.createTestingModule for unit/integration, mocking providers, e2e tests with INestApplication + supertest, ORM mocking (TypeORM/Prisma/Mongoose), test fixtures. Use this skill to: - Write unit tests for services with mocked dependencies. - Write integration tests with real DI but mocked external services. - Write e2e tests for HTTP endpoints via supertest. - Mock repositories/Prisma client correctly. - Cover services and controllers to ≥80%. Do NOT use this skil...

35 stars
0 votes
0 copies
0 views
Added 9/22/2026
testinggosqltestingapidatabasefrontend

Works with

cliapi

Security Analysis

A92/100
mediumInstalls packages at runtime which could introduce malicious dependencies

Scanned 9/22/2026

Install to Claude Code

$npx -y skills add AratKruglik/claude-sdlc --skill nest-testing --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Nest Testing?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Nest Testing
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/aratkruglik-nest-testing/badge)](https://www.skillsdirectory.com/skills/aratkruglik-nest-testing)

More formats (shields.io, HTML) on the badges page.

Download with Pro
Files
SKILL.md
---
name: nest-testing
description: |
  NestJS testing patterns: Test.createTestingModule for unit/integration, mocking providers, e2e tests with INestApplication + supertest, ORM mocking (TypeORM/Prisma/Mongoose), test fixtures.

  Use this skill to:
  - Write unit tests for services with mocked dependencies.
  - Write integration tests with real DI but mocked external services.
  - Write e2e tests for HTTP endpoints via supertest.
  - Mock repositories/Prisma client correctly.
  - Cover services and controllers to ≥80%.

  Do NOT use this skill for:
  - Test framework setup (Jest/Vitest config — usually already in place).
  - Frontend tests.
  - Load testing (out of QA scope).
user-invocable: false
paths: ["**/*.spec.ts", "test/**"]
---

# NestJS Testing

NestJS has a first-class testing module. The pattern: build a synthetic IoC container with the providers you want, override what you need, and exercise the system.

## Test framework

Default in Nest CLI is Jest. If the project uses Vitest, the patterns translate 1:1 — the imports change (`@nestjs/testing` works with both).

Test scripts in `package.json`:

```json
{
  "scripts": {
    "test": "jest",
    "test:watch": "jest --watch",
    "test:cov": "jest --coverage",
    "test:e2e": "jest --config ./test/jest-e2e.json"
  }
}
```

E2E tests live in `test/` (or `apps/<app>/test/` in monorepo) and use a separate Jest config that picks up `*.e2e-spec.ts`.

## Unit test — service with mocked deps

```ts
// src/users/users.service.spec.ts
import { Test, TestingModule } from '@nestjs/testing';
import { getRepositoryToken } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { UsersService } from './users.service';
import { User } from './entities/user.entity';

describe('UsersService', () => {
  let service: UsersService;
  let repo: jest.Mocked<Repository<User>>;

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      providers: [
        UsersService,
        {
          provide: getRepositoryToken(User),
          useValue: {
            findOne: jest.fn(),
            find: jest.fn(),
            save: jest.fn(),
            create: jest.fn(),
            delete: jest.fn(),
          },
        },
      ],
    }).compile();

    service = module.get(UsersService);
    repo = module.get(getRepositoryToken(User));
  });

  it('finds a user by email', async () => {
    const user = { id: '1', email: 'a@b.c' } as User;
    repo.findOne.mockResolvedValue(user);
    expect(await service.findByEmail('a@b.c')).toBe(user);
    expect(repo.findOne).toHaveBeenCalledWith({ where: { email: 'a@b.c' } });
  });

  it('returns null when not found', async () => {
    repo.findOne.mockResolvedValue(null);
    expect(await service.findByEmail('missing@b.c')).toBeNull();
  });
});
```

Key points:
- Use `getRepositoryToken(Entity)` as the provider token — TypeORM's `@InjectRepository` resolves to this.
- Type the mock as `jest.Mocked<Repository<User>>` for autocomplete and type safety on `mockResolvedValue` / `mockRejectedValue`.

## Mocking Prisma

```ts
import { mockDeep, DeepMockProxy } from 'jest-mock-extended';
import { PrismaClient } from '@prisma/client';

let prisma: DeepMockProxy<PrismaClient>;

beforeEach(async () => {
  prisma = mockDeep<PrismaClient>();
  const module = await Test.createTestingModule({
    providers: [
      UsersService,
      { provide: PrismaService, useValue: prisma },
    ],
  }).compile();
  service = module.get(UsersService);
});

it('creates a user', async () => {
  const created = { id: '1', email: 'a@b.c' };
  prisma.user.create.mockResolvedValue(created as any);
  const result = await service.create({ email: 'a@b.c', password: 'secret' });
  expect(result).toEqual(created);
});
```

`jest-mock-extended` (`pnpm add -D jest-mock-extended`) provides typed deep mocks — Prisma's nested API (`prisma.user.create`, `prisma.user.findMany`) gets full type info.

## Mocking Mongoose

```ts
import { getModelToken } from '@nestjs/mongoose';

const userModelMock = {
  findOne: jest.fn().mockReturnValue({ exec: jest.fn() }),
  create: jest.fn(),
  // ...
};

beforeEach(async () => {
  const module = await Test.createTestingModule({
    providers: [
      UsersService,
      { provide: getModelToken(User.name), useValue: userModelMock },
    ],
  }).compile();
});
```

Mongoose's chained API (`.findOne().exec()`) makes mocks fiddly — return `{ exec: jest.fn() }` from each query method.

## Integration test — real container, mocked external services

For controllers with services, often you want real DI through the controller-service-repository chain but mock the database:

```ts
const module = await Test.createTestingModule({
  controllers: [UsersController],
  providers: [
    UsersService,
    { provide: getRepositoryToken(User), useValue: repoMock },
    { provide: MailerService, useValue: { send: jest.fn().mockResolvedValue(undefined) } },
  ],
})
  .overrideGuard(JwtAuthGuard)
  .useValue({ canActivate: () => true })
  .compile();
```

`.overrideGuard(...).useValue(...)` is the cleanest way to bypass auth in tests.

## E2E test

```ts
// test/users.e2e-spec.ts
import { Test, TestingModule } from '@nestjs/testing';
import { INestApplication, ValidationPipe } from '@nestjs/common';
import * as request from 'supertest';
import { AppModule } from '../src/app.module';

describe('UsersController (e2e)', () => {
  let app: INestApplication;

  beforeAll(async () => {
    const module: TestingModule = await Test.createTestingModule({
      imports: [AppModule],
    })
      .overrideProvider(MailerService).useValue({ send: jest.fn() })
      .compile();

    app = module.createNestApplication();
    app.useGlobalPipes(new ValidationPipe({ whitelist: true, forbidNonWhitelisted: true }));
    await app.init();
  });

  afterAll(async () => {
    await app.close();
  });

  it('POST /users → 201', async () => {
    const res = await request(app.getHttpServer())
      .post('/users')
      .send({ email: 'new@user.com', password: 'longenough' })
      .expect(201);
    expect(res.body).toMatchObject({ email: 'new@user.com' });
    expect(res.body).not.toHaveProperty('passwordHash');
  });

  it('POST /users with extra field → 400', async () => {
    await request(app.getHttpServer())
      .post('/users')
      .send({ email: 'a@b.c', password: 'longenough', isAdmin: true })
      .expect(400);                         // forbidNonWhitelisted catches this
  });
});
```

Use `app.getHttpServer()` (not `app.listen()`) — supertest binds to a random port itself.

For database, prefer:
- A test container (Postgres/Mongo via Testcontainers) per suite.
- Or a separate test database with migrations applied in `beforeAll`.
- Or in-memory (sqlite-memory for TypeORM, mongo-memory-server) for speed — caveat: subtle differences from real DB.

## E2E test database setup pattern

```ts
beforeAll(async () => {
  const module = await Test.createTestingModule({
    imports: [AppModule],
  })
    .overrideProvider(getDataSourceToken())
    .useFactory({
      factory: async () => {
        const ds = new DataSource({
          type: 'sqlite',
          database: ':memory:',
          entities: [User, Order],
          synchronize: true,                 // OK in tests
        });
        await ds.initialize();
        return ds;
      },
    })
    .compile();
  // ...
});
```

## Test fixtures

For repeated entities, factory functions:

```ts
// test/factories/user.factory.ts
import { faker } from '@faker-js/faker';
import { User } from '../../src/users/entities/user.entity';

export const userFactory = (overrides: Partial<User> = {}): User => ({
  id: faker.string.uuid(),
  email: faker.internet.email(),
  passwordHash: '$argon2id$...',
  metadata: {},
  createdAt: new Date(),
  updatedAt: new Date(),
  ...overrides,
} as User);
```

Use `userFactory({ email: 'specific@x.com' })` in tests to override what matters and get reasonable defaults for the rest.

## Coverage discipline

Target ≥80% for **services** and **controllers**. These hold business logic.

Don't measure coverage on:
- Modules (`*.module.ts`) — pure configuration.
- Decorator definitions — DSL, not logic.
- DTOs/entities — schemas, not logic.
- `main.ts` — bootstrap.

Configure Jest to exclude:

```jsonc
// package.json
{
  "jest": {
    "collectCoverageFrom": [
      "src/**/*.{ts,js}",
      "!src/**/*.module.ts",
      "!src/**/*.dto.ts",
      "!src/**/*.entity.ts",
      "!src/main.ts"
    ]
  }
}
```

## Iteration cap (from QA agent)

The qa-engineer agent has a hard 3-attempt cap on fixing failing tests. If a test is fundamentally fragile after 3 attempts, mark it `it.skip(...)` with a comment explaining why and report in the QA summary. Don't iterate past the cap.

## Anti-patterns

- ❌ Sharing mock state between tests without `beforeEach` reset.
- ❌ Real database calls in unit tests (slow, flaky).
- ❌ E2E tests against `localhost:3000` — use `app.getHttpServer()` so each test creates its own port.
- ❌ Asserting on `body.passwordHash` not being there as the only protection — also test that the endpoint excludes it via DTO/serializer.
- ❌ `expect(spy).toHaveBeenCalled()` without `.toHaveBeenCalledWith(...)` — half a test.
- ❌ Long e2e tests that exercise dozens of routes — split per resource.
- ❌ Mocking the SUT (test the real thing; mock its deps).

Attribution

AratKruglikAratKruglik
View sourceMore from AratKruglik →
SSkills DirectorySkills Directory

Know which skills are safe — weekly.

Best new skills + every skill we flagged as malicious. From the team that scanned 103,619.

Join free

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Know which skills are safe — weekly.

Best new skills + every skill we flagged as malicious. From the team that scanned 103,619.

Join free

Related Skills

Screen Reader Testing

Practical guide to testing web applications with screen readers for comprehensive accessibility validation.

397921 votes

Golang Testing

Go测试模式包括表格驱动测试、子测试、基准测试、模糊测试和测试覆盖率。遵循TDD方法论,采用地道的Go实践。

2456590 votes

Springboot Tdd

使用JUnit 5、Mockito、MockMvc、Testcontainers和JaCoCo进行Spring Boot的测试驱动开发。适用于添加功能、修复错误或重构时。

2456590 votes

Tdd Workflow

在编写新功能、修复错误或重构代码时使用此技能。强制执行测试驱动开发,包含单元测试、集成测试和端到端测试,覆盖率超过80%。

2456590 votes

Python Testing

使用pytest、TDD方法、夹具、模拟、参数化和覆盖率要求的Python测试策略。

2456590 votes
View all in testing →