📖 Scenario: You are building a simple NestJS application that manages books. You want to make sure your controller works correctly by writing unit tests for it.
🎯 Goal: Create a unit test for a NestJS controller called BooksController that has a method findAll returning a list of books.
📋 What You'll Learn
Create a BooksController class with a findAll method returning an array of book objects
Create a unit test file for BooksController
Set up a testing module with BooksController in the test
Write a test case that checks findAll returns the expected books array
💡 Why This Matters
🌍 Real World
Unit testing controllers ensures your API endpoints behave as expected before deploying your NestJS application.
💼 Career
Writing unit tests for controllers is a key skill for backend developers working with NestJS to maintain reliable and maintainable code.
Progress0 / 4 steps
1
Create the BooksController with findAll method
Create a class called BooksController with a method findAll that returns this exact array: [{ id: 1, title: '1984' }, { id: 2, title: 'Brave New World' }].
NestJS
Hint
Define a class with a method that returns the exact array of book objects.
2
Set up the testing module with BooksController
In a test file, import Test and TestingModule from @nestjs/testing. Create a variable booksController. Use beforeEach to create a testing module with BooksController as a controller and assign the controller instance to booksController.
NestJS
Hint
Use NestJS testing utilities to create a module and get the controller instance.
3
Write a test case for findAll method
Inside the describe block, add a test case with it named 'should return an array of books'. Inside it, call booksController.findAll() and expect the result to equal the exact array [{ id: 1, title: '1984' }, { id: 2, title: 'Brave New World' }].
NestJS
Hint
Write a test that calls findAll and checks the returned array matches exactly.
4
Complete the test file with proper imports and structure
Add the import statement for describe, it, and expect from @jest/globals at the top. Ensure the test file exports nothing and contains the full test suite for BooksController with the test case for findAll.
NestJS
Hint
Jest globals like describe, it, and expect should be imported explicitly.
Practice
(1/5)
1. What is the main purpose of unit testing a controller in NestJS?
easy
A. To verify the controller handles requests correctly without depending on other parts
B. To test the database connection and queries
C. To check the UI rendering of the application
D. To measure the performance of the entire application
Solution
Step 1: Understand the role of a controller
Controllers handle incoming requests and return responses, so testing them focuses on this behavior.
Step 2: Identify what unit testing isolates
Unit testing isolates the controller from other parts like services or databases to test its logic alone.
Final Answer:
To verify the controller handles requests correctly without depending on other parts -> Option A
Quick Check:
Unit testing controller logic = To verify the controller handles requests correctly without depending on other parts [OK]
Hint: Controllers handle requests; test them isolated from services [OK]
Common Mistakes:
Confusing unit tests with integration tests
Testing database or UI in controller unit tests
Ignoring mocking dependencies
2. Which of the following is the correct way to create a testing module for a controller in NestJS?
easy
A. const module = Test.createModule({ providers: [MyController] });
B. const module = new Module({ controllers: [MyController] });
C. const module = await Test.createTestingModule({ controllers: [MyController] }).compile();
D. const module = await Test.createTestingModule({ services: [MyController] }).compile();
Solution
Step 1: Recall NestJS testing syntax
Use Test.createTestingModule with a config object specifying controllers or providers, then compile it.
Step 2: Identify correct property for controllers
The property to register controllers is 'controllers', not 'services' or 'providers' for controllers.
A. The controller is not created using Test.createTestingModule
B. The test does not mock the service dependency
C. The test is missing async keyword
D. The expect statement uses toBe instead of toEqual
Solution
Step 1: Check controller instantiation
Creating controller directly is allowed but only if it has no dependencies.
Step 2: Identify missing mocking
If the controller depends on a service, it must be mocked to isolate controller logic.
Final Answer:
The test does not mock the service dependency -> Option B
Quick Check:
Missing mocks for dependencies = The test does not mock the service dependency [OK]
Hint: Always mock services when testing controllers with dependencies [OK]
Common Mistakes:
Assuming direct instantiation is always wrong
Forgetting to mock injected services
Confusing toBe and toEqual for strings
5. You want to unit test a NestJS controller method that calls a service method returning a promise. Which approach correctly mocks the service to test the controller method synchronously?
hard
A. Mock the service method with jest.fn().mockResolvedValue(value) and await the controller method in the test
B. Mock the service method with jest.fn().mockReturnValue(value) without async/await
C. Call the real service method without mocking to test actual behavior
D. Mock the service method with jest.fn().mockImplementation(() => { throw new Error(); })
Solution
Step 1: Understand async service method
The service method returns a promise, so the mock must simulate a resolved promise.
Step 2: Use jest.fn().mockResolvedValue
This creates a mock that returns a resolved promise with the given value, allowing the controller method to await it.
Step 3: Await controller method in test
The test must await the controller method to handle the async call properly.
Final Answer:
Mock the service method with jest.fn().mockResolvedValue(value) and await the controller method in the test -> Option A
Quick Check:
Use mockResolvedValue and await async calls = Mock the service method with jest.fn().mockResolvedValue(value) and await the controller method in the test [OK]
Hint: Use mockResolvedValue for async mocks and await calls [OK]
Common Mistakes:
Using mockReturnValue for async methods
Not awaiting async controller methods
Testing real service instead of mocking
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.