Unit Testing Angular Applications
Unit testing in Angular ensures that individual units of code work as expected. This guide covers the basics of setting up and writing unit tests for Angular applications using Jasmine and Karma.
Setting Up Unit Testing
Angular CLI comes with Jasmine and Karma pre-configured. To create a new Angular project with unit testing setup:
ng new my-app
Writing Unit Tests
Write unit tests for your components, services, and other classes in the *.spec.ts
files. For example, to test a component:
// app.component.spec.ts
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { AppComponent } from './app.component';
describe('AppComponent', () => {
let component: AppComponent;
let fixture: ComponentFixture;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [AppComponent]
}).compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(AppComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create the app', () => {
expect(component).toBeTruthy();
});
it(`should have as title 'my-app'`, () => {
expect(component.title).toEqual('my-app');
});
it('should render title', () => {
const compiled = fixture.nativeElement;
expect(compiled.querySelector('.content span').textContent).toContain('my-app app is running!');
});
});
Testing Services
Write unit tests for services by injecting them into the test bed:
// my-service.service.spec.ts
import { TestBed } from '@angular/core/testing';
import { MyService } from './my-service.service';
describe('MyService', () => {
let service: MyService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(MyService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
it('should return expected value', () => {
expect(service.getValue()).toBe('expected value');
});
});
Mocking Dependencies
Use Jasmine spies to mock dependencies and test interactions:
// my-component.component.spec.ts
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { MyComponent } from './my-component.component';
import { MyService } from '../my-service.service';
describe('MyComponent', () => {
let component: MyComponent;
let fixture: ComponentFixture;
let myServiceSpy: jasmine.SpyObj;
beforeEach(async () => {
const spy = jasmine.createSpyObj('MyService', ['getValue']);
await TestBed.configureTestingModule({
declarations: [MyComponent],
providers: [{ provide: MyService, useValue: spy }]
}).compileComponents();
myServiceSpy = TestBed.inject(MyService) as jasmine.SpyObj;
});
beforeEach(() => {
fixture = TestBed.createComponent(MyComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should call getValue on MyService', () => {
myServiceSpy.getValue.and.returnValue('mock value');
component.ngOnInit();
expect(myServiceSpy.getValue).toHaveBeenCalled();
});
});
Running Unit Tests
Run your unit tests using the Angular CLI:
ng test
Code Coverage
Generate a code coverage report using the Angular CLI:
ng test --code-coverage
The coverage report will be generated in the coverage
folder.
Debugging Unit Tests
Debug your unit tests in the browser by adding the debugger
statement in your test code and running:
ng test --browsers Chrome
Key Points
- Unit testing in Angular ensures that individual units of code work as expected.
- Angular CLI comes with Jasmine and Karma pre-configured for unit testing.
- Write unit tests for your components, services, and other classes in the
*.spec.ts
files. - Use the test bed to create test environments and inject dependencies.
- Use Jasmine spies to mock dependencies and test interactions.
- Run your unit tests using the Angular CLI command
ng test
. - Generate a code coverage report using the
ng test --code-coverage
command. - Debug your unit tests in the browser by adding the
debugger
statement and runningng test --browsers Chrome
.
Conclusion
Unit testing is crucial for ensuring the reliability and maintainability of your Angular applications. By writing comprehensive unit tests, mocking dependencies, and generating code coverage reports, you can build robust and error-free applications. Happy testing!