0
0
AngularHow-ToBeginner · 4 min read

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 TestBed with the directive and host component.
  • Create a fixture for the host component.
  • Use fixture.debugElement.query to find the element with the directive.
  • Access the directive instance via injector.get or componentInstance.
  • 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 TestBed declarations 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.