Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
40 prioritized NestJS best practices across architecture, DI, security, performance, testing, and microservices.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
rules/test-e2e-supertest.md
1---2title: Use Supertest for E2E Testing3impact: HIGH4impactDescription: Validates the full request/response cycle5tags: testing, e2e, supertest, integration6---78## Use Supertest for E2E Testing910End-to-end tests use Supertest to make real HTTP requests against your NestJS application. They test the full stack including middleware, guards, pipes, and interceptors. E2E tests catch integration issues that unit tests miss.1112**Incorrect (no proper E2E setup or teardown):**1314```typescript15// Only unit test controllers16describe('UsersController', () => {17it('should return users', async () => {18const service = { findAll: jest.fn().mockResolvedValue([]) };19const controller = new UsersController(service as any);2021const result = await controller.findAll();2223expect(result).toEqual([]);24// Doesn't test: routes, guards, pipes, serialization25});26});2728// E2E tests without proper setup/teardown29describe('Users API', () => {30it('should create user', async () => {31const app = await NestFactory.create(AppModule);32// No proper initialization33// No cleanup after test34// Hits real database35});36});37```3839**Correct (proper E2E setup with Supertest):**4041```typescript42// Proper E2E test setup43import { Test, TestingModule } from '@nestjs/testing';44import { INestApplication, ValidationPipe } from '@nestjs/common';45import * as request from 'supertest';46import { AppModule } from '../src/app.module';4748describe('UsersController (e2e)', () => {49let app: INestApplication;5051beforeAll(async () => {52const moduleFixture: TestingModule = await Test.createTestingModule({53imports: [AppModule],54}).compile();5556app = moduleFixture.createNestApplication();5758// Apply same config as production59app.useGlobalPipes(60new ValidationPipe({61whitelist: true,62transform: true,63forbidNonWhitelisted: true,64}),65);6667await app.init();68});6970afterAll(async () => {71await app.close();72});7374describe('/users (POST)', () => {75it('should create a user', () => {76return request(app.getHttpServer())77.post('/users')78.send({ name: 'John', email: '[email protected]' })79.expect(201)80.expect((res) => {81expect(res.body).toHaveProperty('id');82expect(res.body.name).toBe('John');83expect(res.body.email).toBe('[email protected]');84});85});8687it('should return 400 for invalid email', () => {88return request(app.getHttpServer())89.post('/users')90.send({ name: 'John', email: 'invalid-email' })91.expect(400)92.expect((res) => {93expect(res.body.message).toContain('email');94});95});96});9798describe('/users/:id (GET)', () => {99it('should return 404 for non-existent user', () => {100return request(app.getHttpServer())101.get('/users/non-existent-id')102.expect(404);103});104});105});106107// Testing with authentication108describe('Protected Routes (e2e)', () => {109let app: INestApplication;110let authToken: string;111112beforeAll(async () => {113const moduleFixture = await Test.createTestingModule({114imports: [AppModule],115}).compile();116117app = moduleFixture.createNestApplication();118app.useGlobalPipes(new ValidationPipe({ whitelist: true }));119await app.init();120121// Get auth token122const loginResponse = await request(app.getHttpServer())123.post('/auth/login')124.send({ email: '[email protected]', password: 'password' });125126authToken = loginResponse.body.accessToken;127});128129it('should return 401 without token', () => {130return request(app.getHttpServer())131.get('/users/me')132.expect(401);133});134135it('should return user profile with valid token', () => {136return request(app.getHttpServer())137.get('/users/me')138.set('Authorization', `Bearer ${authToken}`)139.expect(200)140.expect((res) => {141expect(res.body.email).toBe('[email protected]');142});143});144});145146// Database isolation for E2E tests147describe('Orders API (e2e)', () => {148let app: INestApplication;149let dataSource: DataSource;150151beforeAll(async () => {152const moduleFixture = await Test.createTestingModule({153imports: [154ConfigModule.forRoot({155envFilePath: '.env.test', // Test database config156}),157AppModule,158],159}).compile();160161app = moduleFixture.createNestApplication();162dataSource = moduleFixture.get(DataSource);163await app.init();164});165166beforeEach(async () => {167// Clean database between tests168await dataSource.synchronize(true);169});170171afterAll(async () => {172await dataSource.destroy();173await app.close();174});175});176```177178Reference: [NestJS E2E Testing](https://docs.nestjs.com/fundamentals/testing#end-to-end-testing)179