angular-testing
SKILL.md
Angular Testing - Quick Reference
Deep Knowledge: Use
mcp__documentation__fetch_docswith technology:angular, topic:testingfor comprehensive documentation.
Standalone Component Testing
import { ComponentFixture, TestBed } from '@angular/core/testing';
describe('UserListComponent', () => {
let component: UserListComponent;
let fixture: ComponentFixture<UserListComponent>;
let userService: jasmine.SpyObj<UserService>;
beforeEach(async () => {
const spy = jasmine.createSpyObj('UserService', ['getUsers']);
await TestBed.configureTestingModule({
imports: [UserListComponent],
providers: [{ provide: UserService, useValue: spy }],
}).compileComponents();
fixture = TestBed.createComponent(UserListComponent);
component = fixture.componentInstance;
userService = TestBed.inject(UserService) as jasmine.SpyObj<UserService>;
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should load users', () => {
const mockUsers = [{ id: 1, name: 'Alice' }];
userService.getUsers.and.returnValue(of(mockUsers));
component.loadUsers();
expect(component.users()).toEqual(mockUsers);
expect(component.count()).toBe(1);
});
});
Service Testing
import { TestBed } from '@angular/core/testing';
import { provideHttpClient } from '@angular/common/http';
import { provideHttpClientTesting, HttpTestingController } from '@angular/common/http/testing';
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).toEqual(mockUsers);
});
const req = httpMock.expectOne('/api/users');
expect(req.request.method).toBe('GET');
req.flush(mockUsers);
});
it('should handle 404', () => {
service.getById(999).subscribe({
error: (err) => expect(err.message).toContain('not found'),
});
const req = httpMock.expectOne('/api/users/999');
req.flush(null, { status: 404, statusText: 'Not Found' });
});
});
Testing Signals
it('should update signal value', () => {
component.count.set(5);
expect(component.count()).toBe(5);
expect(component.double()).toBe(10);
});
it('should compute derived values', () => {
component.users.set([{ id: 1, name: 'A' }, { id: 2, name: 'B' }]);
expect(component.count()).toBe(2);
});
Testing Forms
it('should validate required fields', () => {
component.form.controls.name.setValue('');
expect(component.form.controls.name.hasError('required')).toBeTrue();
component.form.controls.name.setValue('Alice');
expect(component.form.controls.name.valid).toBeTrue();
});
it('should submit valid form', () => {
component.form.patchValue({ name: 'Alice', email: 'alice@test.com' });
expect(component.form.valid).toBeTrue();
});
Testing Guards
import { TestBed } from '@angular/core/testing';
import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
describe('authGuard', () => {
it('should allow authenticated users', () => {
TestBed.configureTestingModule({
providers: [{ provide: AuthService, useValue: { isAuthenticated: () => true } }],
});
const result = TestBed.runInInjectionContext(() =>
authGuard({} as ActivatedRouteSnapshot, {} as RouterStateSnapshot)
);
expect(result).toBeTrue();
});
});
Anti-Patterns
| Anti-Pattern | Why It's Bad | Correct Approach |
|---|---|---|
| Testing implementation details | Brittle tests | Test behavior and outputs |
Not using httpMock.verify() |
Undetected HTTP issues | Always verify in afterEach |
| Real HTTP in unit tests | Flaky, slow | Use HttpTestingController |
| Not testing error paths | Incomplete coverage | Test error scenarios |
Weekly Installs
12
Repository
claude-dev-suit…ev-suiteGitHub Stars
2
First Seen
10 days ago
Security Audits
Installed on
cursor11
gemini-cli11
amp11
cline11
github-copilot11
codex11