Skip to content
Skillv1.0.0

nestjs-testing-expert

NestJS testing mechanics with Jest — building testing modules, mocking providers and repositories, writing service and controller specs, and driving HTTP end-to-end tests through the real application.

by shipshitdev(0) 0 installs
Free
Sign in to install

Free account. Installing gives you the manifest plus copy-paste snippets.

See reviews

About

Imported from shipshitdev/skills (skills/nestjs-testing-expert/SKILL.md) via skills.sh. Install upstream with npx skills add shipshitdev/skills --skill nestjs-testing-expert. Copyright stays with the author.

NestJS Testing Expert

Build reliable Jest suites for NestJS modules, services, controllers, and HTTP endpoints.

Scope

This skill owns NestJS mechanics: testing modules, provider wiring, and request-level end-to-end flows. For framework-agnostic questions — which level a behavior belongs at, what a coverage number means, how to design a test that survives refactoring, how to kill a flake — use testing-expert.

When to Use

  • Writing unit, integration, or end-to-end tests for a NestJS application
  • Setting up a testing module, overriding providers, or faking a database
  • Testing controllers, guards, interceptors, or pipes
  • Exercising HTTP endpoints against a booted Nest application

Levels in a Nest Application

  • Unit — a service or provider in isolation, collaborators replaced with test doubles. No module graph beyond the providers under test.
  • Integration — a module compiled with its real providers, external systems faked. Proves the wiring and the contracts between layers.
  • End-to-end — a booted application driven over HTTP. Proves the full request path: pipes, guards, controller, service, persistence.

Service Specs

Compile a testing module with the subject real and every collaborator supplied explicitly. Injection tokens come from whatever integration provides them — an ORM's token helper, a class reference, or a custom token constant.

describe('UsersService', () => {
  let service: UsersService;
  let repository: jest.Mocked<UsersRepository>;

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      providers: [
        UsersService,
        { provide: UsersRepository, useValue: createUsersRepositoryMock() },
      ],
    }).compile();

    service = module.get(UsersService);
    repository = module.get(UsersRepository);
  });

  afterEach(() => {
    jest.resetAllMocks();
  });

  it('returns only the active users of the requested organization', async () => {
    const expected = [{ id: '1', organization: 'org1' }];
    repository.find.mockResolvedValue(expected);

    const result = await service.findAll('org1');

    expect(result).toEqual(expected);
    expect(repository.find).toHaveBeenCalledWith({
      organization: 'org1',
      isDeleted: false,
    });
  });
});

Assert on the arguments the collaborator received when they encode a business rule — the isDeleted: false filter above is the behavior, not an implementation detail.

Controller Specs

Register the controller, stub its service, and verify only the controller's own job: argument extraction, delegation, and response shaping. Business rules belong to the service spec.

describe('UsersController', () => {
  let controller: UsersController;
  let service: jest.Mocked<UsersService>;

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      controllers: [UsersController],
      providers: [{ provide: UsersService, useValue: createUsersServiceMock() }],
    }).compile();

    controller = module.get(UsersController);
    service = module.get(UsersService);
  });

  it('passes the organization from the request through to the service', async () => {
    const expected = [{ id: '1', email: 'test@example.com' }];
    service.findAll.mockResolvedValue(expected);

    const result = await controller.findAll('org1');

    expect(result).toEqual(expected);
    expect(service.findAll).toHaveBeenCalledWith('org1');
  });
});

Overriding Providers

Compile the real module and swap only what must not run for real. overrideProvider and overrideGuard keep the rest of the graph authentic, so the test still proves the wiring.

const module: TestingModule = await Test.createTestingModule({
  imports: [UsersModule],
})
  .overrideProvider(MailerService)
  .useValue(mailerMock)
  .overrideGuard(AuthGuard)
  .useValue({ canActivate: () => true })
  .compile();

Override the guard only in tests about something else. Authorization itself deserves end-to-end tests that run the real guard.

Integration Tests

Boot the application, keep persistence real against a disposable database, and reset state between tests.

describe('Users (integration)', () => {
  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();
  });

  beforeEach(async () => {
    await resetDatabase();
  });

  it('persists a created user and returns it on read', async () => {
    const created = await request(app.getHttpServer())
      .post('/api/users')
      .send({ email: 'test@example.com', name: 'Test' })
      .expect(201);

    const read = await request(app.getHttpServer())
      .get(`/api/users/${created.body.id}`)
      .expect(200);

    expect(read.body.email).toBe('test@example.com');
  });
});

Close the application in afterAll. A leaked Nest application holds its connection pool open and hangs the Jest run.

End-to-End Tests

Same boot, driven as a real client — authentication included.

describe('Users API (e2e)', () => {
  let app: INestApplication;
  let authToken: string;

  beforeAll(async () => {
    const moduleFixture: TestingModule = await Test.createTestingModule({
      imports: [AppModule],
    }).compile();

    app = moduleFixture.createNestApplication();
    await app.init();

    authToken = await signInTestUser(app);
  });

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

  it('rejects an unauthenticated list request', () =>
    request(app.getHttpServer()).get('/api/users').expect(401));

  it('returns the caller organization users when authenticated', () =>
    request(app.getHttpServer())
      .get('/api/users')
      .set('Authorization', `Bearer ${authToken}`)
      .expect(200)
      .expect((res) => {
        expect(Array.isArray(res.body)).toBe(true);
      }));
});

A shared signInTestUser helper keeps the token flow in one place and out of every spec.

Database Strategy

Approach Fits Cost
Repository test double Unit specs Fastest; proves no SQL or schema
In-memory or embedded engine Integration specs Fast; behavior can drift from production
Disposable container per run Integration and e2e specs Slowest; highest fidelity

Reset between tests by truncating or rolling back a transaction rather than recreating the schema — schema rebuilds dominate suite runtime.

Tips

  • Give each spec its own module compilation; a shared one leaks state between tests.
  • Reset mocks in afterEach so a stub set in one test cannot satisfy the next.
  • Boot the application once per describe block and reset data per test — booting per test is the usual cause of a slow Nest suite.
  • Keep tests deterministic: freeze the clock and pin the timezone rather than asserting on the real one.

Checklist

  • Clear arrange/act/assert structure
  • Subject real, collaborators explicit — never the reverse
  • Error and unauthorized paths covered, not just the happy path
  • Application closed and mocks reset in teardown
  • Fast to run

Use it

Copy one of these into your project. Installing also returns the manifest and these snippets.

yaml
targets:
  - https://api.opensmartroute.ai/api/v1/registry/shipshitdev-skills-nestjs-testing-expert/manifest   # or paste the manifest below

Manifest

An Open Capability Manifest: the router reads it to know what this does, what it costs and when to pick it.

shipshitdev-skills-nestjs-testing-expert.ocm.jsonjson
{
  "ocm": "1",
  "id": "shipshitdev-skills-nestjs-testing-expert",
  "kind": "skill",
  "name": "nestjs-testing-expert",
  "description": "NestJS testing mechanics with Jest — building testing modules, mocking providers and repositories, writing service and controller specs, and driving HTTP end-to-end tests through the real application. Use for any test touching a NestJS service, controller, guard, module, or API endpoint, including test-module setup, provider overrides, database fakes, and Supertest request flows.",
  "publisher": "shipshitdev",
  "version": "1.0.0",
  "capabilities": {
    "domains": [
      "coding"
    ],
    "tags": [
      "skill-md",
      "nestjs",
      "testing",
      "jest",
      "supertest",
      "backend",
      "skills-sh"
    ],
    "languages": [
      "en"
    ]
  },
  "quality_prior": 0.6,
  "examples": [
    "NestJS testing mechanics with Jest — building testing modules, mocking providers and repositories, writing service and controller specs, and driving HTTP end-to-end tests through the real application. Use for any test touching a NestJS service, controller, guard, module, or API endpoint, including test-module setup, provider overrides, database fakes, and Supertest request flows."
  ],
  "primary": false,
  "metadata": {
    "source": {
      "provider": "skills.sh",
      "repository": "https://github.com/shipshitdev/skills",
      "path": "skills/nestjs-testing-expert/SKILL.md",
      "ref": "HEAD",
      "url": "https://www.skills.sh/shipshitdev/skills/nestjs-testing-expert",
      "key": "shipshitdev/skills/skills/nestjs-testing-expert/SKILL.md"
    }
  },
  "instructions": "# NestJS Testing Expert\n\nBuild reliable Jest suites for NestJS modules, services, controllers, and HTTP\nendpoints.\n\n## Scope\n\nThis skill owns NestJS mechanics: testing modules, provider wiring, and\nrequest-level end-to-end flows. For framework-agnostic questions — which level a\nbehavior belongs at, what a coverage number means, how to design a test that\nsurvives refactoring, how to kill a flake — use `testing-expert`.\n\n## When to Use\n\n- Writing unit, integration, or end-to-end tests for a NestJS application\n- Setting up a testing module, overriding providers, or faking a database\n- Testing con",
  "cost": {
    "context_tokens": 1830
  }
}

Fetch it by URL: GET /api/v1/registry/shipshitdev-skills-nestjs-testing-expert/manifest?version=1.0.0

Reviews

Star ratings from people who tried it. One review per account; edit yours any time.

No reviews yet. Install it, try it, and be the first to rate it.