How to Test Directive in Angular: Simple Guide with Example
To test a
directive in Angular, create a test host component that uses the directive, then use Angular's TestBed to compile and create a fixture for it. Access the directive instance via fixture.debugElement.query and assert its behavior or DOM changes.Syntax
Testing a directive involves these steps:
- Create a test host component that applies the directive.
- Configure
TestBedwith the directive and host component. - Create a fixture for the host component.
- Use
fixture.debugElement.queryto find the element with the directive. - Access the directive instance via
injector.getorcomponentInstance. - Assert the directive's effects or properties.
typescript
import { Component } from '@angular/core'; import { Directive } from '@angular/core'; import { TestBed, ComponentFixture } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; @Directive({ selector: '[appExample]' }) class ExampleDirective { // directive logic } @Component({ template: `<div appExample></div>` }) class TestHostComponent {} // In test: // TestBed.configureTestingModule({ declarations: [ExampleDirective, TestHostComponent] }); // fixture = TestBed.createComponent(TestHostComponent); // const directiveEl = fixture.debugElement.query(By.directive(ExampleDirective)); // const directiveInstance = directiveEl.injector.get(ExampleDirective);
Example
This example shows how to test a directive that changes the background color of an element.
typescript
import { Directive, ElementRef, Renderer2 } from '@angular/core'; import { Component } from '@angular/core'; import { TestBed, ComponentFixture } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; @Directive({ selector: '[appHighlight]' }) class HighlightDirective { constructor(private el: ElementRef, private renderer: Renderer2) { this.renderer.setStyle(this.el.nativeElement, 'backgroundColor', 'yellow'); } } @Component({ template: `<p appHighlight>Highlight me!</p>` }) class TestHostComponent {} describe('HighlightDirective', () => { let fixture: ComponentFixture<TestHostComponent>; beforeEach(() => { TestBed.configureTestingModule({ declarations: [HighlightDirective, TestHostComponent] }); fixture = TestBed.createComponent(TestHostComponent); fixture.detectChanges(); }); it('should highlight the background color', () => { const pEl = fixture.debugElement.query(By.css('p')); const bgColor = pEl.nativeElement.style.backgroundColor; expect(bgColor).toBe('yellow'); }); });
Output
PASS: should highlight the background color
Common Pitfalls
- Not declaring the directive in the
TestBeddeclarations causes errors. - Forgetting to create a host component to apply the directive makes testing impossible.
- Not calling
fixture.detectChanges()means directive lifecycle hooks won't run. - Trying to test directive logic without accessing the directive instance or DOM element can miss effects.
typescript
/* Wrong: Missing directive in declarations */ TestBed.configureTestingModule({ declarations: [TestHostComponent] // Missing directive here }); /* Right: Include directive */ TestBed.configureTestingModule({ declarations: [HighlightDirective, TestHostComponent] });
Quick Reference
Remember these key points when testing Angular directives:
- Always declare the directive and a host component in
TestBed. - Use
fixture.debugElement.query(By.directive(YourDirective))to find the directive. - Call
fixture.detectChanges()to trigger Angular's change detection. - Check DOM changes or directive properties for assertions.
Key Takeaways
Create a test host component to apply the directive for testing.
Declare both the directive and host component in TestBed before creating the fixture.
Use fixture.debugElement.query with By.directive to access the directive instance.
Always call fixture.detectChanges() to run directive lifecycle hooks.
Assert directive effects by checking DOM or directive properties.