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
describeanditblocks 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/testingto create a test module. - Mock all services the controller depends on.
- Use Jest's
spyOnor 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.