0
0
NestjsHow-ToBeginner ยท 4 min read

How to Test Controller in NestJS: Simple Guide with Example

To test a controller in NestJS, use the TestingModule from @nestjs/testing to create a test module that includes the controller and its dependencies. Then, write unit tests with Jest to call controller methods and check their outputs or behaviors.
๐Ÿ“

Syntax

Testing a NestJS controller involves creating a TestingModule that imports the controller and any required providers. Then you retrieve the controller instance from the module and write tests using Jest.

  • Test.createTestingModule({ controllers: [YourController], providers: [YourService] }): sets up the test module.
  • module.get(YourController): gets the controller instance.
  • Use Jest describe and it blocks to write test cases.
typescript
import { Test, TestingModule } from '@nestjs/testing';
import { YourController } from './your.controller';
import { YourService } from './your.service';

describe('YourController', () => {
  let controller: YourController;

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      controllers: [YourController],
      providers: [YourService],
    }).compile();

    controller = module.get<YourController>(YourController);
  });

  it('should be defined', () => {
    expect(controller).toBeDefined();
  });
});
๐Ÿ’ป

Example

This example shows how to test a simple AppController with a method that returns a greeting string. It uses a mock service to isolate the controller test.

typescript
import { Test, TestingModule } from '@nestjs/testing';
import { AppController } from './app.controller';
import { AppService } from './app.service';

describe('AppController', () => {
  let appController: AppController;
  let appService: AppService;

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      controllers: [AppController],
      providers: [AppService],
    }).compile();

    appController = module.get<AppController>(AppController);
    appService = module.get<AppService>(AppService);
  });

  describe('getHello', () => {
    it('should return "Hello World!"', () => {
      jest.spyOn(appService, 'getHello').mockImplementation(() => 'Hello World!');
      expect(appController.getHello()).toBe('Hello World!');
    });
  });
});
Output
PASS ./app.controller.spec.ts AppController getHello โœ“ should return "Hello World!" (5 ms)
โš ๏ธ

Common Pitfalls

Common mistakes when testing NestJS controllers include:

  • Not mocking dependent services, causing tests to fail or be slow.
  • Forgetting to compile the testing module before getting the controller.
  • Testing controller methods that depend on asynchronous services without handling async properly.
  • Not isolating controller logic by mixing service logic in tests.

Always mock services and use async/await if controller methods return promises.

typescript
/* Wrong: No mocking of service */
import { Test, TestingModule } from '@nestjs/testing';
import { AppController } from './app.controller';
import { AppService } from './app.service';

describe('AppController', () => {
  let appController: AppController;

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      controllers: [AppController],
      providers: [AppService],
    }).compile();

    appController = module.get<AppController>(AppController);
  });

  it('should return Hello World', () => {
    // This test depends on real AppService implementation
    expect(appController.getHello()).toBe('Hello World!');
  });
});

/* Right: Mock the service */
const mockAppService = { getHello: () => 'Hello World!' };

describe('AppController with mock', () => {
  let appController: AppController;

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

    appController = module.get<AppController>(AppController);
  });

  it('should return Hello World', () => {
    expect(appController.getHello()).toBe('Hello World!');
  });
});
๐Ÿ“Š

Quick Reference

Tips for testing NestJS controllers:

  • Use @nestjs/testing to create a test module.
  • Mock all services the controller depends on.
  • Use Jest's spyOn or provide mock implementations.
  • Test controller methods directly by calling them.
  • Handle async methods with async/await.
โœ…

Key Takeaways

Use TestingModule from @nestjs/testing to set up controller tests.
Mock dependent services to isolate controller logic.
Write tests with Jest calling controller methods directly.
Handle asynchronous controller methods with async/await.
Always compile the testing module before accessing the controller.