Chapter 16: Testing in Angular (Standalone Components)
Testing is a vital part of developing robust Angular applications. With Angular 20’s support for standalone components, writing unit and end-to-end (E2E) tests is streamlined using modern tools like Jasmine, Karma, and Cypress. This chapter focuses on setting up test environments and writing test cases for services and standalone components.
1. Unit Testing with Jasmine & Karma
Angular provides built-in support for Jasmine
(test framework) and Karma
(test runner). When you create a component using Angular CLI, a corresponding .spec.ts
test file is also generated.
Example: Standalone Component Unit Test
import { Component } from '@angular/core';
@Component({
standalone: true,
selector: 'app-greet',
template: `
Hello {{ name }}
` }) export class GreetComponent { name = ‘Angular’; }
// greet.component.spec.ts
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { GreetComponent } from './greet.component';
describe('GreetComponent', () => {
let fixture: ComponentFixture<GreetComponent>;
let component: GreetComponent;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [GreetComponent]
}).compileComponents();
fixture = TestBed.createComponent(GreetComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should render greeting with default name', () => {
const compiled = fixture.nativeElement as HTMLElement;
expect(compiled.querySelector('h1')?.textContent).toContain('Hello Angular');
});
});
2. TestBed & Mock Services
TestBed
is Angular’s primary API for configuring and initializing test environments. When working with services, you often mock dependencies to isolate the unit under test.
Example: Mocking a Service
// my.service.ts
export class MyService {
getMessage() {
return 'Real Message';
}
}
// my.component.ts
import { Component, inject } from '@angular/core';
import { MyService } from './my.service';
@Component({
standalone: true,
selector: 'app-my',
template: `{{ message }}`,
providers: [MyService]
})
export class MyComponent {
message = inject(MyService).getMessage();
}
// my.component.spec.ts
class MockService {
getMessage() {
return 'Mocked Message';
}
}
describe('MyComponent', () => {
let fixture: ComponentFixture<MyComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [MyComponent],
providers: [{ provide: MyService, useClass: MockService }]
}).compileComponents();
fixture = TestBed.createComponent(MyComponent);
fixture.detectChanges();
});
it('should show mocked message', () => {
const compiled = fixture.nativeElement as HTMLElement;
expect(compiled.textContent).toContain('Mocked Message');
});
});
3. End-to-End (E2E) Testing
For E2E testing, Angular previously used Protractor
, but modern stacks recommend Cypress for faster, more reliable tests.
Basic Cypress Test Example
// cypress/e2e/app.cy.js
describe('App Component', () => {
it('loads the home page', () => {
cy.visit('/');
cy.contains('Angular').should('exist');
});
});
4. Summary
- Use Jasmine + Karma for unit testing Angular standalone components.
- Mock services in tests to isolate logic and avoid side effects.
- Use TestBed to configure test environments dynamically.
- For E2E testing, use Cypress for better performance and developer experience.
Next Chapter Preview
Next, Chapter 17 covers a Real-World CRUD Project using Angular Material and API integration. You’ll learn to build a functional to-do or task manager application using standalone components.