How to test Angular directives
Angular directives modify DOM behavior and appearance, making testing essential to ensure they work correctly across different scenarios and edge cases. With over 12 years of Angular development experience since 2014 and as the creator of CoreUI, I’ve tested numerous custom directives in production applications. Testing directives requires creating a test component that uses the directive, then asserting that the directive correctly modifies the DOM or behavior. This approach verifies both attribute directives that change element behavior and structural directives that modify the DOM structure.
Create a test component that applies the directive and verify its behavior using TestBed.
For an attribute directive that highlights elements:
// highlight.directive.ts
import { Directive, ElementRef, Input, OnInit } from '@angular/core'
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective implements OnInit {
@Input() appHighlight = 'yellow'
constructor(private el: ElementRef) {}
ngOnInit() {
this.el.nativeElement.style.backgroundColor = this.appHighlight
}
}
Test the directive:
// highlight.directive.spec.ts
import { Component } from '@angular/core'
import { ComponentFixture, TestBed } from '@angular/core/testing'
import { HighlightDirective } from './highlight.directive'
@Component({
template: `
<div appHighlight>Default highlight</div>
<div [appHighlight]="'red'">Red highlight</div>
`
})
class TestComponent {}
describe('HighlightDirective', () => {
let fixture: ComponentFixture<TestComponent>
let elements: HTMLElement[]
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [HighlightDirective, TestComponent]
})
fixture = TestBed.createComponent(TestComponent)
fixture.detectChanges()
elements = fixture.nativeElement.querySelectorAll('div')
})
it('should apply default yellow background', () => {
expect(elements[0].style.backgroundColor).toBe('yellow')
})
it('should apply custom red background', () => {
expect(elements[1].style.backgroundColor).toBe('red')
})
})
For structural directives:
it('should render element when condition is true', () => {
component.show = true
fixture.detectChanges()
const element = fixture.nativeElement.querySelector('.content')
expect(element).toBeTruthy()
})
Best Practice Note
Use a dedicated test component rather than testing the directive in isolation—this tests how the directive actually works in a real template. For directives with inputs, test with various input values including edge cases like null or undefined. Use DebugElement for more robust queries that work across platforms. Test directive lifecycle hooks to ensure proper initialization and cleanup. This is the same approach we use in CoreUI for Angular—thorough directive testing to ensure UI enhancements work reliably across all supported browsers and Angular versions.



