Mocking providers helps you test parts of your NestJS app without using real services. It makes tests faster and safer.
Mocking providers in NestJS
const mockProvider = {
provide: ServiceToMock,
useValue: {
methodName: jest.fn().mockReturnValue(mockValue),
},
};provide is the token or class you want to mock.
useValue is the fake object with mocked methods.
UserService with a fake findUser method returning a test user.const mockUserService = {
provide: UserService,
useValue: {
findUser: jest.fn().mockReturnValue({ id: 1, name: 'Test' }),
},
};LoggerService with a log method that does nothing but can track calls.const mockLogger = {
provide: LoggerService,
useValue: {
log: jest.fn(),
},
};This test mocks UsersService inside the test module. The UsersController uses the mock instead of the real service. The test checks that findAll returns the mocked user list and that the service method was called.
import { Test } from '@nestjs/testing'; import { UsersController } from './users.controller'; import { UsersService } from './users.service'; describe('UsersController', () => { let usersController: UsersController; let usersService: UsersService; const mockUsersService = { findAll: jest.fn().mockReturnValue([{ id: 1, name: 'Alice' }]), }; beforeEach(async () => { const moduleRef = await Test.createTestingModule({ controllers: [UsersController], providers: [ { provide: UsersService, useValue: mockUsersService, }, ], }).compile(); usersController = moduleRef.get<UsersController>(UsersController); usersService = moduleRef.get<UsersService>(UsersService); }); it('should return an array of users', () => { expect(usersController.findAll()).toEqual([{ id: 1, name: 'Alice' }]); expect(usersService.findAll).toHaveBeenCalled(); }); });
Use jest.fn() to create mock functions that can track calls and return values.
Mocking helps keep tests fast and independent from external systems.
Remember to reset mocks between tests if needed to avoid test interference.
Mocking providers replaces real services with fake ones in tests.
This helps isolate the code you want to test and avoid side effects.
Use provide and useValue to define mocks in NestJS test modules.
Practice
Solution
Step 1: Understand the role of mocking in tests
Mocking replaces real dependencies with controlled fake versions to isolate the code under test.Step 2: Identify the purpose in NestJS context
In NestJS, mocking providers helps avoid side effects and external calls during testing.Final Answer:
To replace real services with fake ones to isolate tests -> Option AQuick Check:
Mocking = isolate tests [OK]
- Thinking mocking speeds up production
- Confusing mocking with adding features
- Assuming mocking generates data automatically
Solution
Step 1: Recall NestJS mocking syntax
Mocking uses an object with keys 'provide' for the real service and 'useValue' for the mock.Step 2: Match correct key order and values
{ provide: RealService, useValue: mockService } correctly uses 'provide' with the real service and 'useValue' with the mock object.Final Answer:
{ provide: RealService, useValue: mockService } -> Option AQuick Check:
Mock syntax = provide + useValue [OK]
- Swapping provide and useValue keys
- Using useClass instead of useValue for mocks
- Putting mock as provide instead of real service
const mockUserService = { findUser: () => ({ id: 1, name: 'Test' }) };
const moduleRef = await Test.createTestingModule({
providers: [
{ provide: UserService, useValue: mockUserService },
],
}).compile();
const service = moduleRef.get(UserService);
const user = service.findUser();
console.log(user);
What will be logged to the console?Solution
Step 1: Understand the mock provider setup
The mockUserService has a method findUser returning an object with id and name.Step 2: Check what service.findUser() returns
Since the mock is used, calling findUser() returns { id: 1, name: 'Test' } as defined.Final Answer:
{ id: 1, name: 'Test' } -> Option CQuick Check:
Mock method returns object [OK]
- Expecting real service output instead of mock
- Assuming service is undefined
- Confusing method with object itself
TypeError: service.findUser is not a function. What is the likely cause?
const mockUserService = {};
const moduleRef = await Test.createTestingModule({
providers: [
{ provide: UserService, useValue: mockUserService },
],
}).compile();
const service = moduleRef.get(UserService);
service.findUser();Solution
Step 1: Check the mock object definition
The mockUserService is an empty object with no findUser method defined.Step 2: Understand the error cause
Calling findUser on an object without that method causes TypeError.Final Answer:
The mockUserService does not define the findUser method -> Option DQuick Check:
Missing method in mock = TypeError [OK]
- Assuming compile() missing await causes this error
- Confusing useClass and useValue for mocks
- Thinking provider missing causes this specific error
Solution
Step 1: Understand mocking async methods
To mock a method returning a promise resolved with 'done', use Promise.resolve('done').Step 2: Check each option for correct promise return
{ provide: DepService, useValue: { asyncMethod: () => Promise.resolve('done') } } correctly returns Promise.resolve('done'). { provide: DepService, useValue: { asyncMethod: () => 'done' } } returns a string, not a promise. { provide: DepService, useValue: { asyncMethod: () => async () => 'done' } } returns a function, not a promise. { provide: DepService, useValue: { asyncMethod: () => new Promise('done') } } incorrectly uses new Promise with a string argument.Final Answer:
{ provide: DepService, useValue: { asyncMethod: () => Promise.resolve('done') } } -> Option BQuick Check:
Mock async with Promise.resolve(value) [OK]
- Returning plain value instead of promise
- Incorrect new Promise usage
- Confusing async function syntax with promise return
Ready to prove it?
Pass the test and this pattern moves unknown
