Mocking services helps you test components without using real data or making real requests. It makes tests faster and more reliable.
Mocking services in tests in Angular
Start learning this pattern below
Jump into concepts and practice - no test required
or
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Introduction
Syntax
Angular
class MockService { methodName() { return expectedValue; } } TestBed.configureTestingModule({ providers: [ { provide: RealService, useClass: MockService } ] });
Use useClass to replace the real service with a mock class.
You can also use useValue to provide a simple object as a mock.
Examples
Angular
class MockUserService { getUser() { return { id: 1, name: 'Test User' }; } } TestBed.configureTestingModule({ providers: [ { provide: UserService, useClass: MockUserService } ] });
useValue to provide a simple mock object with a method.Angular
const mockUserService = { getUser: () => ({ id: 2, name: 'Mock User' }) }; TestBed.configureTestingModule({ providers: [ { provide: UserService, useValue: mockUserService } ] });
Sample Program
This test replaces the real UserService with MockUserService. The component uses the mock to get user data. The test checks that the component shows the mocked user name.
Angular
import { TestBed } from '@angular/core/testing'; import { Component } from '@angular/core'; import { UserService } from './user.service'; class MockUserService { getUser() { return { id: 1, name: 'Mocked User' }; } } @Component({ selector: 'app-user', template: '<p>{{ userName }}</p>' }) class UserComponent { userName = ''; constructor(private userService: UserService) { const user = this.userService.getUser(); this.userName = user.name; } } describe('UserComponent with mocked service', () => { let component: UserComponent; beforeEach(() => { TestBed.configureTestingModule({ declarations: [UserComponent], providers: [ { provide: UserService, useClass: MockUserService } ] }); const fixture = TestBed.createComponent(UserComponent); component = fixture.componentInstance; fixture.detectChanges(); }); it('should display mocked user name', () => { expect(component.userName).toBe('Mocked User'); }); });
Important Notes
Always mock only what you need to keep tests simple.
Use spies if you want to check if a service method was called.
Remember to configure the testing module before creating the component.
Summary
Mocking services lets you test components without real dependencies.
Use useClass or useValue to provide mocks in Angular tests.
Mocking makes tests faster, more reliable, and easier to control.
Practice
1. What is the main purpose of mocking services in Angular tests?
easy
Solution
Step 1: Understand the role of mocking
Mocking replaces real dependencies with controlled fake versions to isolate the component under test.Step 2: Identify the testing benefit
This isolation helps tests run faster and more reliably without depending on real service behavior.Final Answer:
To replace real services with fake ones for isolated testing -> Option DQuick Check:
Mocking = Replace real with fake [OK]
Hint: Mocking means replacing real services with fakes in tests [OK]
Common Mistakes:
- Thinking mocking speeds up production app
- Confusing mocking with adding features
- Believing mocking auto-generates code
2. Which syntax correctly provides a mock service using
useClass in Angular test setup?easy
Solution
Step 1: Recall Angular provider syntax
Angular expects an object with 'provide' as the token and 'useClass' as the mock class.Step 2: Match correct order and keys
The correct order is 'provide' first, then 'useClass' with the mock class.Final Answer:
providers: [{ provide: RealService, useClass: MockService }] -> Option AQuick Check:
Provide token, then useClass mock [OK]
Hint: Remember: provide token first, then useClass mock class [OK]
Common Mistakes:
- Swapping provide and useClass keys
- Using useValue instead of useClass incorrectly
- Providing mock as token instead of real service
3. Given this Angular test setup, what will
component.getData() return?class MockService {
fetch() { return 'mocked data'; }
}
TestBed.configureTestingModule({
providers: [{ provide: RealService, useClass: MockService }]
});
const service = TestBed.inject(RealService);
const component = new MyComponent(service);
component.getData = function() { return this.service.fetch(); };medium
Solution
Step 1: Identify the injected service
The test replaces RealService with MockService using useClass, so service is an instance of MockService.Step 2: Trace method call in component
component.getData calls service.fetch(), which returns 'mocked data' from MockService.Final Answer:
'mocked data' -> Option CQuick Check:
MockService fetch() returns 'mocked data' [OK]
Hint: Injected service is mock, so method returns mock's value [OK]
Common Mistakes:
- Assuming real service is used
- Expecting undefined instead of mock return
- Thinking method throws error without real service
4. What is wrong with this Angular test provider setup?
providers: [{ provide: RealService, useValue: MockService }]medium
Solution
Step 1: Understand useValue usage
useValue expects an actual instance or object, not a class reference.Step 2: Identify the mistake
MockService is a class, but useValue is given the class itself, not an instance like new MockService().Final Answer:
useValue expects an instance, not a class reference -> Option BQuick Check:
useValue needs instance, not class [OK]
Hint: useValue needs instance (new), not class name [OK]
Common Mistakes:
- Passing class instead of instance to useValue
- Confusing provide token with mock class
- Assuming useValue can't be used in providers
5. You want to mock a service method that returns different values on consecutive calls in Angular tests. Which approach correctly achieves this?
hard
Solution
Step 1: Understand requirement for different returns
Returning different values on consecutive calls requires state tracking inside the mock method.Step 2: Choose correct mocking approach
A mock class with a call count variable can track calls and return different values accordingly.Step 3: Evaluate other options
useValue with fixed return can't vary returns; overriding real service method is complex; spying alone doesn't mock service.Final Answer:
Create a mock class with a method using a call count variable to return different values -> Option AQuick Check:
Mock class with state tracks calls for varied returns [OK]
Hint: Use mock class with call count to vary method returns [OK]
Common Mistakes:
- Using fixed return object for varying outputs
- Overriding real service instead of mocking
- Relying only on spies without mocks
