E2E testing checks if your whole app works well from start to finish. Supertest helps you test your NestJS app by simulating real HTTP requests.
E2E testing with supertest in NestJS
import request from 'supertest'; import { INestApplication } from '@nestjs/common'; // inside your test block await request(app.getHttpServer()) .get('/your-route') .expect(200) .expect('Content-Type', /json/);
Use app.getHttpServer() to get the server instance from your NestJS app.
Chain .expect() to check status codes and response headers or body.
await request(app.getHttpServer()) .get('/users') .expect(200);
await request(app.getHttpServer()) .post('/auth/login') .send({ username: 'test', password: '1234' }) .expect(201) .expect(res => { if (!('token' in res.body)) throw new Error('Missing token'); });
This is a simple E2E test for a NestJS app. It starts the app, sends a GET request to the root route, and expects a 200 status with 'Hello World!' text. Finally, it closes the app.
import { Test, TestingModule } from '@nestjs/testing'; import { INestApplication } from '@nestjs/common'; import * as request from 'supertest'; import { AppModule } from '../src/app.module'; describe('AppController (e2e)', () => { let app: INestApplication; beforeAll(async () => { const moduleFixture: TestingModule = await Test.createTestingModule({ imports: [AppModule], }).compile(); app = moduleFixture.createNestApplication(); await app.init(); }); it('/ (GET)', () => { return request(app.getHttpServer()) .get('/') .expect(200) .expect('Hello World!'); }); afterAll(async () => { await app.close(); }); });
Always call await app.init() before sending requests.
Close the app with await app.close() to free resources.
Use .send() to add data for POST or PUT requests.
E2E testing checks your app as a whole using real HTTP calls.
Supertest works well with NestJS to simulate these calls.
Write tests that start the app, send requests, check responses, and close the app.
Practice
supertest in NestJS E2E testing?Solution
Step 1: Understand E2E testing goal
E2E testing checks the entire app by simulating real HTTP requests and responses.Step 2: Role of supertest in NestJS
Supertest helps send HTTP requests to the running NestJS app and verify responses, enabling full app behavior testing.Final Answer:
To simulate HTTP requests and test the whole app behavior -> Option DQuick Check:
E2E testing = simulate HTTP requests [OK]
- Confusing supertest with mocking libraries
- Thinking supertest is for styling or compiling
- Using supertest only for unit tests
supertest in a NestJS E2E test file?Solution
Step 1: Check ES module import style
In modern NestJS with ES modules,import * as request from 'supertest';is the correct syntax to import all exports as an object.Step 2: Identify incorrect options
const request = require('supertest'); uses CommonJS require, which is discouraged in ES module projects. import request from 'supertest'; assumes default export which supertest does not have. const request = import('supertest'); is invalid syntax.Final Answer:
import * as request from 'supertest'; -> Option BQuick Check:
Use ES module import * as for supertest [OK]
- Using require() instead of import
- Assuming supertest has a default export
- Using dynamic import incorrectly
const app = await NestFactory.create(AppModule);
await app.init();
return request(app.getHttpServer())
.get('/users')
.expect(200);
Solution
Step 1: Analyze the test request
The test sends a GET request to '/users' on the initialized app and expects status 200.Step 2: Understand .expect(200) behavior
The .expect(200) asserts the response status must be 200 for the test to pass.Final Answer:
200 -> Option AQuick Check:
Test expects status 200, so response = 200 [OK]
- Confusing expected status with actual response
- Assuming 404 if route not defined without context
- Ignoring .expect() assertion meaning
const app = await NestFactory.create(AppModule);
return request(app.getHttpServer())
.post('/login')
.send({ username: 'user', password: 'pass' })
.expect(201);
await app.close();Solution
Step 1: Check code flow with return and await
Thereturnstatement ends the function immediately, soawait app.close()after return is unreachable and never runs.Step 2: Identify proper app closing
To close the app properly,await app.close()must be called before returning the request promise.Final Answer:
Calling app.close() after return statement -> Option CQuick Check:
Code after return is unreachable [OK]
- Ignoring unreachable code after return
- Thinking .send() is invalid for POST
- Assuming status 201 is always wrong
Solution
Step 1: Initialize and start the app
AwaitNestFactory.create(AppModule)andapp.init()to fully bootstrap and start the HTTP server before sending requests.Step 2: Send POST request and await response
Await the supertest chainrequest(app.getHttpServer()).post('/items').send({ name: 'item1' }).expect(201)to capture theresponseobject.Step 3: Verify response body and close app
Assertexpect(response.body).toHaveProperty('id')then awaitapp.close()for proper cleanup.Final Answer:
The snippet with await app.init(), await request.expect(201), body check, and await app.close() -> Option AQuick Check:
Await init, await request, assert body, await close [OK]
- Not awaiting app.init() before requests
- Not awaiting request call causing missing response
- Expecting wrong status code (200 vs 201)
- Calling app.close() too early or after return
Ready to prove it?
Pass the test and this pattern moves unknown
