Bird
Raised Fist0
NestJSframework~10 mins

E2E testing with supertest in NestJS - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - E2E testing with supertest
Start Test Suite
↓
Initialize NestJS App
↓
Use supertest to send HTTP request
↓
Receive HTTP response
↓
Check response status and body
↓
Pass or Fail Test
↓
Close App and End Test
The test starts by setting up the NestJS app, then supertest sends an HTTP request. The response is checked for expected status and data, then the test ends.
Execution Sample
NestJS
import request from 'supertest';
import { Test } from '@nestjs/testing';
import { AppModule } from '../src/app.module';

describe('AppController (e2e)', () => {
  let app;
  beforeAll(async () => {
    const moduleRef = await Test.createTestingModule({ imports: [AppModule] }).compile();
    app = moduleRef.createNestApplication();
    await app.init();
  });

  it('/ (GET)', () => {
    return request(app.getHttpServer())
      .get('/')
      .expect(200)
      .expect('Hello World!');
  });

  afterAll(async () => {
    await app.close();
  });
});
This code sets up a NestJS app, sends a GET request to '/', expects status 200 and 'Hello World!' response, then closes the app.
Execution Table
StepActionEvaluationResult
1Start test suiteN/ATest suite begins
2Create testing module with AppModuleModule createdModuleRef ready
3Create Nest app from moduleApp instance createdApp initialized
4Call app.init()App ready to receive requestsApp listening
5supertest sends GET request to '/'Request sentWaiting for response
6Receive responseStatus 200, Body 'Hello World!'Response matches expectation
7Test passesExpectations metTest success
8Call app.close()App shuts downResources freed
9Test suite endsN/AAll tests complete
💡 Test ends after app closes and all expectations pass
Variable Tracker
VariableStartAfter Step 2After Step 3After Step 4After Step 6After Step 8Final
moduleRefundefinedModuleRef instanceModuleRef instanceModuleRef instanceModuleRef instanceModuleRef instanceModuleRef instance
appundefinedundefinedNest app instanceApp initializedApp initializedApp closedApp closed
responseundefinedundefinedundefinedundefined{status:200, body:'Hello World!'}{status:200, body:'Hello World!'}{status:200, body:'Hello World!'}
Key Moments - 3 Insights
Why do we call app.init() before sending requests?
app.init() prepares the NestJS app to handle HTTP requests. Without it, supertest cannot send requests properly. See step 4 in execution_table.
What happens if the response status is not 200?
The test fails because the expectation in step 6 is not met. The test runner will report an error at this step.
Why do we call app.close() after tests?
Calling app.close() frees resources and stops the server. This prevents hanging processes after tests finish, as shown in step 8.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the app state after step 4?
AApp is closed
BApp is not initialized
CApp is ready to receive requests
DApp is sending a request
💡 Hint
Check the 'Result' column at step 4 in execution_table
At which step does supertest receive the HTTP response?
AStep 5
BStep 6
CStep 7
DStep 8
💡 Hint
Look for 'Receive response' action in execution_table
If app.close() is not called, what might happen?
AThe test process may hang after tests finish
BThe app will not start
CTests will fail immediately
DThe response status will be 500
💡 Hint
Refer to step 8 and key_moments about app.close()
Concept Snapshot
E2E testing with supertest in NestJS:
- Setup Nest app with Test.createTestingModule
- Call app.init() to start server
- Use supertest to send HTTP requests
- Check response status and body with expect
- Close app with app.close() after tests
- Ensures full app behavior tested via HTTP
Full Transcript
This visual execution shows how to do end-to-end testing in NestJS using supertest. First, the test suite starts and creates a testing module with the app's main module. Then, it creates a NestJS app instance and calls app.init() to prepare it for HTTP requests. Next, supertest sends a GET request to the root path '/'. The app responds with status 200 and body 'Hello World!'. The test checks these values and passes if they match. Finally, the app is closed to free resources and end the test cleanly. Key points include calling app.init() before requests and app.close() after tests to avoid hanging processes.

Practice

(1/5)
1. What is the main purpose of using supertest in NestJS E2E testing?
easy
A. To style the frontend components
B. To mock database calls inside unit tests
C. To compile TypeScript code before running tests
D. To simulate HTTP requests and test the whole app behavior

Solution

  1. Step 1: Understand E2E testing goal

    E2E testing checks the entire app by simulating real HTTP requests and responses.
  2. 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.
  3. Final Answer:

    To simulate HTTP requests and test the whole app behavior -> Option D
  4. Quick Check:

    E2E testing = simulate HTTP requests [OK]
Hint: Remember: supertest sends HTTP requests to test app end-to-end [OK]
Common Mistakes:
  • Confusing supertest with mocking libraries
  • Thinking supertest is for styling or compiling
  • Using supertest only for unit tests
2. Which of the following is the correct way to import and use supertest in a NestJS E2E test file?
easy
A. const request = import('supertest');
B. import * as request from 'supertest';
C. import request from 'supertest';
D. const request = require('supertest');

Solution

  1. 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.
  2. 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.
  3. Final Answer:

    import * as request from 'supertest'; -> Option B
  4. Quick Check:

    Use ES module import * as for supertest [OK]
Hint: Use import * as request from 'supertest' in NestJS E2E tests [OK]
Common Mistakes:
  • Using require() instead of import
  • Assuming supertest has a default export
  • Using dynamic import incorrectly
3. Given this NestJS E2E test snippet, what will be the HTTP status code returned by the test?
const app = await NestFactory.create(AppModule);
await app.init();
return request(app.getHttpServer())
  .get('/users')
  .expect(200);
medium
A. 200
B. 404
C. 500
D. 301

Solution

  1. Step 1: Analyze the test request

    The test sends a GET request to '/users' on the initialized app and expects status 200.
  2. Step 2: Understand .expect(200) behavior

    The .expect(200) asserts the response status must be 200 for the test to pass.
  3. Final Answer:

    200 -> Option A
  4. Quick Check:

    Test expects status 200, so response = 200 [OK]
Hint: Check the .expect() status code to predict response [OK]
Common Mistakes:
  • Confusing expected status with actual response
  • Assuming 404 if route not defined without context
  • Ignoring .expect() assertion meaning
4. Identify the error in this NestJS E2E test code snippet:
const app = await NestFactory.create(AppModule);
return request(app.getHttpServer())
  .post('/login')
  .send({ username: 'user', password: 'pass' })
  .expect(201);
await app.close();
medium
A. Using .send() with POST request is invalid
B. Missing await before request call
C. Calling app.close() after return statement
D. Expecting status 201 instead of 200

Solution

  1. Step 1: Check code flow with return and await

    The return statement ends the function immediately, so await app.close() after return is unreachable and never runs.
  2. Step 2: Identify proper app closing

    To close the app properly, await app.close() must be called before returning the request promise.
  3. Final Answer:

    Calling app.close() after return statement -> Option C
  4. Quick Check:

    Code after return is unreachable [OK]
Hint: Place app.close() before return to ensure cleanup [OK]
Common Mistakes:
  • Ignoring unreachable code after return
  • Thinking .send() is invalid for POST
  • Assuming status 201 is always wrong
5. You want to write an E2E test in NestJS that sends a POST request with JSON data, verifies the response body contains a specific property, and then closes the app properly. Which code snippet correctly implements this?
hard
A. const app = await NestFactory.create(AppModule); await app.init(); const response = await request(app.getHttpServer()) .post('/items') .send({ name: 'item1' }) .expect(201); expect(response.body).toHaveProperty('id'); await app.close();
B. const app = await NestFactory.create(AppModule); const response = request(app.getHttpServer()) .post('/items') .send({ name: 'item1' }) .expect(201); expect(response.body).toHaveProperty('id'); await app.close();
C. const app = await NestFactory.create(AppModule); await app.init(); request(app.getHttpServer()) .post('/items') .send({ name: 'item1' }) .expect(201) .then(response => { expect(response.body).toHaveProperty('id'); }); await app.close();
D. const app = await NestFactory.create(AppModule); await app.init(); const response = await request(app.getHttpServer()) .post('/items') .send({ name: 'item1' }) .expect(200); expect(response.body).toHaveProperty('id'); await app.close();

Solution

  1. Step 1: Initialize and start the app

    Await NestFactory.create(AppModule) and app.init() to fully bootstrap and start the HTTP server before sending requests.
  2. Step 2: Send POST request and await response

    Await the supertest chain request(app.getHttpServer()).post('/items').send({ name: 'item1' }).expect(201) to capture the response object.
  3. Step 3: Verify response body and close app

    Assert expect(response.body).toHaveProperty('id') then await app.close() for proper cleanup.
  4. Final Answer:

    The snippet with await app.init(), await request.expect(201), body check, and await app.close() -> Option A
  5. Quick Check:

    Await init, await request, assert body, await close [OK]
Hint: Always await app.init(), request, and app.close() in E2E tests [OK]
Common Mistakes:
  • 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
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard