1. Unit Testing (Jasmine & Karma)
Angular uses Jasmine for writing test cases and Karma as a test runner.
- Jasmine: Testing framework for writing assertions
- Karma: Executes tests in real browsers
Example: Basic unit test
import { TestBed } from '@angular/core/testing';
import { CalculatorService } from './calculator.service';
describe('CalculatorService', () => {
let service: CalculatorService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(CalculatorService);
});
it('should add numbers correctly', () => {
expect(service.add(2, 3)).toBe(5);
});
});
Run tests:
2. Component Testing
Test Angular components using TestBed:
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { UserComponent } from './user.component';
import { By } from '@angular/platform-browser';
describe('UserComponent', () => {
let component: UserComponent;
let fixture: ComponentFixture<UserComponent>;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [UserComponent]
}).compileComponents();
fixture = TestBed.createComponent(UserComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should display username', () => {
component.user = { name: 'Chinmaya' };
fixture.detectChanges();
const nameEl = fixture.debugElement.query(By.css('p')).nativeElement;
expect(nameEl.textContent).toContain('Chinmaya');
});
});
3. Service Testing
Test services independently:
import { TestBed } from '@angular/core/testing';
import { UserService } from './user.service';
describe('UserService', () => {
let service: UserService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(UserService);
});
it('should return users array', () => {
const users = service.getUsers();
expect(users.length).toBeGreaterThan(0);
});
});
4. Mocking HTTP
Use HttpClientTestingModule and HttpTestingController to mock HTTP calls:
import { TestBed } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { ApiService } from './api.service';
describe('ApiService', () => {
let service: ApiService;
let httpMock: HttpTestingController;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [ApiService]
});
service = TestBed.inject(ApiService);
httpMock = TestBed.inject(HttpTestingController);
});
it('should fetch users', () => {
const mockUsers = [{ name: 'Chinmaya' }];
service.getUsers().subscribe(users => {
expect(users).toEqual(mockUsers);
});
const req = httpMock.expectOne('/api/users');
expect(req.request.method).toBe('GET');
req.flush(mockUsers);
});
afterEach(() => {
httpMock.verify();
});
});
5. End-to-End Testing (Cypress / Protractor)
Protractor
- Angular default E2E tool
- Tests user flows in real browser
Example:
describe('Angular App', () => {
it('should display welcome message', () => {
browser.get('/');
expect(element(by.css('h1')).getText()).toEqual('Welcome to My App!');
});
});
Cypress
- Modern E2E testing framework
- Simple syntax, faster, and supports screenshots & videos
Example:
describe('Home Page', () => {
it('displays welcome message', () => {
cy.visit('/');
cy.contains('Welcome to My App!');
});
});
Summary
- Unit testing: Jasmine for assertions, Karma for running tests
- Component testing: Test template rendering and component logic
- Service testing: Test service methods independently
- Mock HTTP calls: Use HttpClientTestingModule for API testing
- E2E testing: Use Protractor or Cypress to test user workflows
- Maintain high test coverage for reliable and maintainable Angular apps