Bird
Raised Fist0
NestJSframework~10 mins

Integration testing in NestJS - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Integration testing
Setup Test Module
↓
Initialize Application
↓
Run Test Cases
↓
Send HTTP Requests
↓
Check Responses & Database
↓
Tear Down Application
↓
Report Results
Integration testing in NestJS sets up a test module, runs HTTP requests against the app, checks responses and database, then cleans up.
Execution Sample
NestJS
import { Test, TestingModule } from '@nestjs/testing';
import { INestApplication } from '@nestjs/common';
import * as request from 'supertest';
import { AppModule } from '../src/app.module';

describe('AppController (integration)', () => {
  let app: INestApplication;

  beforeAll(async () => {
    const moduleRef: TestingModule = await Test.createTestingModule({ imports: [AppModule] }).compile();
    app = moduleRef.createNestApplication();
    await app.init();
  });

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

  afterAll(async () => {
    await app.close();
  });
});
This code sets up a NestJS app for testing, sends a GET request to '/hello', checks the response, then closes the app.
Execution Table
StepActionEvaluationResult
1Create testing module with AppModuleModule createdModuleRef ready
2Create Nest application from moduleApp instance createdapp initialized
3Call app.init()App starts listening internallyApp ready for requests
4Send GET request to '/hello'Request sentResponse received
5Check response statusStatus is 200Pass
6Check response bodyBody is 'Hello World!'Pass
7Call app.close()App shuts downResources released
8Test suite endsAll tests passedIntegration test success
💡 Test ends after app closes and all assertions pass
Variable Tracker
VariableStartAfter Step 1After Step 2After Step 3After Step 4After Step 7Final
appundefinedundefinedNestApplication instanceInitialized appInitialized appClosed appClosed app
Key Moments - 3 Insights
Why do we call app.init() before sending requests?
app.init() starts the NestJS app internally so it can handle HTTP requests, as shown in step 3 of the execution_table.
What happens if we forget to call app.close() after tests?
The app keeps running and resources stay allocated, which can cause tests to hang or leak memory, as explained in step 7.
Why do we use Test.createTestingModule instead of the real app directly?
It creates a test environment isolated from production, allowing controlled testing with modules, as shown in step 1.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the state of 'app' after step 3?
AApp module is created but app not started
BApp is closed and resources released
CApp is initialized and ready to handle requests
DApp is sending HTTP requests
💡 Hint
Check the 'Result' column at step 3 in execution_table
At which step does the test verify the response body is 'Hello World!'?
AStep 4
BStep 6
CStep 5
DStep 7
💡 Hint
Look for 'Check response body' in the 'Action' column in execution_table
If we skip calling app.close(), what impact would it have on the test suite?
ATests might hang or leak resources
BNo impact, tests run normally
CTests would pass faster
DApp would not start
💡 Hint
Refer to the key_moments explanation about app.close() and step 7 in execution_table
Concept Snapshot
Integration testing in NestJS:
- Use Test.createTestingModule({imports: [AppModule]}) to set up
- Create app with moduleRef.createNestApplication()
- Call app.init() to start app internally
- Use supertest (request) to send HTTP calls
- Assert response status and body
- Call app.close() to clean up
- Tests check app behavior end-to-end
Full Transcript
Integration testing in NestJS involves creating a test module with the app's modules, then creating a Nest application instance from it. Before sending HTTP requests, app.init() is called to start the app internally. Tests send requests using supertest and check the responses for expected status codes and bodies. After tests finish, app.close() is called to release resources. This process ensures the app works correctly as a whole, including routing and services.

Practice

(1/5)
1. What is the main purpose of integration testing in NestJS?
easy
A. To test individual functions in isolation
B. To check how different parts of the application work together
C. To measure application performance under load
D. To check the syntax of TypeScript code

Solution

  1. Step 1: Understand integration testing goal

    Integration testing focuses on verifying that multiple parts of the app interact correctly.
  2. Step 2: Differentiate from other test types

    Unit tests check single functions; performance tests measure speed; syntax checks are done by compilers.
  3. Final Answer:

    To check how different parts of the application work together -> Option B
  4. Quick Check:

    Integration testing = check parts working together [OK]
Hint: Integration tests check combined parts, not single functions [OK]
Common Mistakes:
  • Confusing integration with unit testing
  • Thinking integration tests check performance
  • Believing integration tests check code syntax
2. Which of the following is the correct way to initialize a NestJS application for integration testing?
easy
A. const app = await Test.createTestingModule({ imports: [AppModule] }).start();
B. const app = new AppModule(); app.start();
C. const app = await Test.createTestingModule({ controllers: [AppController] }).init();
D. const app = (await Test.createTestingModule({ imports: [AppModule] }).compile()).createNestApplication(); await app.init();

Solution

  1. Step 1: Recognize correct testing module setup

    Use Test.createTestingModule with imports and then compile() to build the module.
  2. Step 2: Create app instance and initialize

    After compiling, create the app with createNestApplication() then call app.init() to start the NestJS app for testing.
  3. Final Answer:

    const app = (await Test.createTestingModule({ imports: [AppModule] }).compile()).createNestApplication(); await app.init(); -> Option D
  4. Quick Check:

    compile() -> createNestApplication() -> init() [OK]
Hint: Always compile() -> createNestApplication() -> init() [OK]
Common Mistakes:
  • Calling init() directly on createTestingModule
  • Using start() method which does not exist
  • Not compiling the testing module before init
3. Given this test snippet, what will be the HTTP status code returned?
const response = await request(app.getHttpServer()).get('/users');
expect(response.status).toBe(200);
medium
A. 200
B. 401
C. 500
D. 404

Solution

  1. Step 1: Understand the test request

    The test sends a GET request to '/users' route using supertest on the initialized app.
  2. Step 2: Check expected status code

    The test expects the response status to be 200, meaning success and route exists.
  3. Final Answer:

    200 -> Option A
  4. Quick Check:

    GET /users returns 200 success [OK]
Hint: 200 means route responded successfully [OK]
Common Mistakes:
  • Confusing 404 (not found) with 200
  • Assuming 500 error without error in code
  • Mixing authentication errors with route success
4. You wrote this integration test but it fails with "Cannot read property 'getHttpServer' of undefined". What is the likely cause?
let app;
beforeAll(async () => {
  app = Test.createTestingModule({ imports: [AppModule] });
  await app.init();
});
medium
A. Forgot to call compile() before init()
B. Used beforeAll instead of beforeEach
C. Did not import supertest library
D. AppModule is missing from imports

Solution

  1. Step 1: Identify missing compile() call

    Test.createTestingModule returns a builder; you must call compile() to get the module instance.
  2. Step 2: Understand why getHttpServer is undefined

    Without compile(), app is not a proper module instance, so app.getHttpServer is undefined causing the error.
  3. Final Answer:

    Forgot to call compile() before init() -> Option A
  4. Quick Check:

    compile() needed before init() [OK]
Hint: Always compile() before init() to get app instance [OK]
Common Mistakes:
  • Skipping compile() step
  • Confusing beforeAll with beforeEach for setup
  • Assuming missing imports cause this error
5. You want to test a POST route that creates a user. Which approach correctly integrates NestJS and supertest for this integration test?
hard
A. Use Jest mocks to simulate the database and skip app initialization
B. Directly call the controller method without app initialization and check returned value
C. Use Test.createTestingModule with AppModule, compile and init app, then use supertest to POST JSON to '/users' endpoint
D. Write a unit test for the service method that creates users

Solution

  1. Step 1: Setup full app for integration test

    Integration tests require the full app context, so createTestingModule with AppModule, compile, and init the app.
  2. Step 2: Use supertest to send POST request

    Use supertest to send a POST request with JSON data to the '/users' route to test real HTTP behavior.
  3. Final Answer:

    Use Test.createTestingModule with AppModule, compile and init app, then use supertest to POST JSON to '/users' endpoint -> Option C
  4. Quick Check:

    Integration test = full app + supertest POST [OK]
Hint: Integration tests use full app and supertest for HTTP calls [OK]
Common Mistakes:
  • Testing controller methods directly without app context
  • Using mocks instead of real modules for integration tests
  • Confusing unit tests with integration tests
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