Testing in Angular - Textnotes

Testing in Angular


Testing ensures your Angular application is robust, maintainable, and bug-free. Angular provides tools for unit testing, component testing, service testing, and end-to-end (E2E) testing.

1. Unit Testing (Jasmine & Karma)

Angular uses Jasmine for writing test cases and Karma as a test runner.

  1. Jasmine: Testing framework for writing assertions
  2. 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:


ng test

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

  1. Angular default E2E tool
  2. 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

  1. Modern E2E testing framework
  2. Simple syntax, faster, and supports screenshots & videos

Example:


describe('Home Page', () => {
it('displays welcome message', () => {
cy.visit('/');
cy.contains('Welcome to My App!');
});
});

Summary

  1. Unit testing: Jasmine for assertions, Karma for running tests
  2. Component testing: Test template rendering and component logic
  3. Service testing: Test service methods independently
  4. Mock HTTP calls: Use HttpClientTestingModule for API testing
  5. E2E testing: Use Protractor or Cypress to test user workflows
  6. Maintain high test coverage for reliable and maintainable Angular apps