What if you could catch bugs instantly without clicking through your app every time?
Why Unit testing services in NestJS? - Purpose & Use Cases
Imagine you build a NestJS service that handles user data. Every time you change the code, you manually test each function by running the app and clicking through the UI to see if it still works.
This manual testing is slow, tiring, and easy to miss bugs. You might forget some cases or introduce errors without noticing. It's like checking every light bulb in a big building by walking room to room instead of having a quick switch test.
Unit testing services lets you write small, automatic tests for each function. NestJS testing tools run these tests quickly and show exactly what works or breaks, so you fix problems early without guessing.
Run app -> Click UI -> Check if data saved correctlyawait expect(service.saveUser(data)).resolves.toEqual(expectedResult)
It enables fast, reliable checks of your service logic anytime you change code, catching bugs before they reach users.
When adding a new feature to send emails, unit tests verify the email service sends correct messages without needing to send real emails every time.
Manual testing is slow and error-prone for service logic.
Unit tests automate checks and catch bugs early.
NestJS provides tools to easily write and run these tests.
Practice
Solution
Step 1: Understand unit testing scope
Unit testing focuses on testing a single piece of code in isolation, here the service alone.Step 2: Identify what unit testing excludes
It excludes integration with other modules or UI, focusing only on the service logic.Final Answer:
To verify the service works correctly on its own without dependencies -> Option AQuick Check:
Unit testing = isolated service check [OK]
- Confusing unit test with integration test
- Thinking unit test covers UI or deployment
- Assuming unit test runs the whole app
Solution
Step 1: Use NestJS TestingModule
In unit tests, you create a TestingModule and get the service instance via module.get.Step 2: Identify correct syntax
The syntax module.get<MyService>(MyService) is the official way to retrieve the service from the test module.Final Answer:
const service = module.get<MyService>(MyService); -> Option CQuick Check:
Use module.get to get service instance [OK]
- Instantiating service directly without module
- Using app.getService which is not a NestJS method
- Using require which is not for NestJS DI
service.getData()?
const mockData = ['a', 'b'];
const mockRepo = { findAll: () => mockData };
const module = await Test.createTestingModule({
providers: [
MyService,
{ provide: MyRepository, useValue: mockRepo },
],
}).compile();
const service = module.get<MyService>(MyService);
console.log(service.getData());Solution
Step 1: Understand mocking of MyRepository
The mockRepo object replaces MyRepository with a findAll method returning ['a', 'b'].Step 2: Analyze service.getData()
Assuming getData calls repository.findAll(), it will return ['a', 'b'] from the mock.Final Answer:
['a', 'b'] -> Option DQuick Check:
Mocked repo returns ['a', 'b'] so service returns same [OK]
- Forgetting to mock repository causing undefined
- Expecting real database call instead of mock
- Assuming empty array without mock data
const module = await Test.createTestingModule({
providers: [MyService],
}).compile();
const service = module.get<MyService>(MyService);
jest.spyOn(service, 'findAll').mockReturnValue(['x', 'y']);Solution
Step 1: Identify what to mock in unit tests
In unit tests, you mock dependencies of the service, not the service's own methods.Step 2: Understand why mocking service method is wrong
Mocking service.findAll replaces the method under test, defeating the purpose of testing it.Final Answer:
The service method findAll should be mocked on the dependency, not service -> Option BQuick Check:
Mock dependencies, not the service itself [OK]
- Mocking the service method instead of its dependencies
- Confusing spyOn usage with mocking dependencies
- Ignoring async test function requirements
Solution
Step 1: Identify dependencies to mock
Since the service calls two repository methods, both should be mocked to isolate service logic.Step 2: Setup test module with mocks
Provide mock implementations for both methods in the test module providers to control their outputs.Step 3: Avoid real calls in unit tests
Calling real repository methods would make it an integration test, not a unit test.Final Answer:
Mock both repository methods with expected return values and inject them into the test module -> Option AQuick Check:
Mock all dependencies to isolate service logic [OK]
- Mocking only some dependencies causing partial isolation
- Calling real methods making it integration test
- Not injecting mocks properly into test module
Ready to prove it?
Pass the test and this pattern moves unknown
