Skip to main content
Practice Problems

Testing in Angular (unit and integration tests)

Testing in Angular

Angular has a built-in testing framework using Jasmine (test runner) and Karma (browser runner), with TestBed for configuring test modules. Modern projects often use Jest as an alternative.


TestBed Setup

typescript
import { ComponentFixture, TestBed } from '@angular/core/testing'; describe('UserComponent', () => { let component: UserComponent; let fixture: ComponentFixture<UserComponent>; beforeEach(async () => { await TestBed.configureTestingModule({ imports: [UserComponent], // Standalone component providers: [ { provide: UserService, useValue: mockUserService } ] }).compileComponents(); fixture = TestBed.createComponent(UserComponent); component = fixture.componentInstance; fixture.detectChanges(); // Trigger initial change detection }); it('should create', () => { expect(component).toBeTruthy(); }); });

Testing Components

typescript
it('should display user name', () => { component.user = { name: 'Alice', email: 'alice@test.com' }; fixture.detectChanges(); const nameEl = fixture.nativeElement.querySelector('h1'); expect(nameEl.textContent).toContain('Alice'); }); it('should emit event on button click', () => { spyOn(component.delete, 'emit'); const button = fixture.nativeElement.querySelector('.delete-btn'); button.click(); expect(component.delete.emit).toHaveBeenCalledWith(component.user.id); });

Testing Services

typescript
describe('UserService', () => { let service: UserService; let httpMock: HttpTestingController; beforeEach(() => { TestBed.configureTestingModule({ providers: [ UserService, provideHttpClient(), provideHttpClientTesting(), ] }); service = TestBed.inject(UserService); httpMock = TestBed.inject(HttpTestingController); }); afterEach(() => { httpMock.verify(); // Ensure no outstanding requests }); it('should fetch users', () => { const mockUsers = [{ id: '1', name: 'Alice' }]; service.getUsers().subscribe(users => { expect(users.length).toBe(1); expect(users[0].name).toBe('Alice'); }); const req = httpMock.expectOne('/api/users'); expect(req.request.method).toBe('GET'); req.flush(mockUsers); // Provide mock response }); });

Mocking Dependencies

typescript
// Create a mock service const mockUserService = { getUsers: jasmine.createSpy().and.returnValue(of([{ name: 'Alice' }])), deleteUser: jasmine.createSpy().and.returnValue(of(void 0)), }; // Or use jasmine.createSpyObj const mockAuth = jasmine.createSpyObj('AuthService', ['login', 'logout', 'isLoggedIn']); mockAuth.isLoggedIn.and.returnValue(true); // Provide in TestBed providers: [ { provide: UserService, useValue: mockUserService }, { provide: AuthService, useValue: mockAuth }, ]

Testing Async Code

typescript
it('should load users on init', fakeAsync(() => { component.ngOnInit(); tick(300); // Simulate debounce fixture.detectChanges(); expect(component.users.length).toBe(1); })); it('should handle async operation', async () => { await component.loadData(); fixture.detectChanges(); expect(component.data).toBeTruthy(); });

Testing Best Practices

PracticeWhy
Mock external dependenciesIsolate the unit being tested
Use fixture.detectChanges()Trigger Angular's change detection
Test behavior, not implementationTests survive refactoring
Use fakeAsync + tickControl async timing
httpMock.verify() in afterEachCatch unexpected HTTP calls
Test edge casesEmpty data, errors, loading states

Important:

Angular testing uses TestBed to configure a testing module with components, services, and mocks. Mock services to isolate units, use HttpTestingController for HTTP tests, and fakeAsync/tick for async operations. Always call fixture.detectChanges() after changing data. Focus on testing behavior — what the user sees and does.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.

Finished reading?
Practice Problems