Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Access Property of Directive in a Test Host in Angular 5?

I am trying to write a it('should toggle menu', () => {}) unit test but have a hard time accessing properties on the directive that contains toggle method..

I have a reusable component that consists of several components/directives

ToggleComponent    
ToggleDirective
ToggleMenuDirective

This is my ToggleDirective:

export class ToggleDirective implements OnInit {
  @HostBinding('class.toggler-toggle') toggleClass = true;
  toggle: boolean;
  visible = false;

  constructor(private toggler: ToggleService, private el: ElementRef) { }
    ngOnInit(): void {
    this.toggler.nowToggle.subscribe(toggle => this.toggle = toggle);
  }
  @HostListener('document:click', ['$event'])
  onVoidClick(): void {
    this.visible = this.el.nativeElement.contains(event.target) ? !this.visible : false;
    this.toggler.setToggleState(this.visible);
  }
}

When writing a unit test I am using the mock template.

How would I access/test methods in ToggleDirective when using a mock template like this:

import { Component } from '@angular/core';
import { TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';

import { TogglerModule } from './toggler.module';

@Component({
  template: `
    <toggler>
      <toggler-toggle>Toggle</toggler-toggle>
      <toggler-menu>
        <toggler-item>Sample Item 1</toggler-item>
      </toggler-menu>
    </toggler>`,
    })
class TestComponent {}

describe('TogglerComponent', () => {

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [TogglerModule],
      declarations: [TestComponent],
    })
    .compileComponents();
  });

  it('should create toggler', () => {
    expect(TestBed.createComponent(TestComponent).componentInstance).toBeTruthy();
  });

  it('should toggle menu', () => {
    const fixture = TestBed.createComponent(TestComponent);
    const component = fixture.componentInstance;
    expect(component.visible).toBeFalsy();
    component.onVoidClick();
    expect(component.visible).toBeTruthy();
  });

});
like image 734
GRowing Avatar asked May 30 '18 18:05

GRowing


1 Answers

You can access the directive using the debugElement's injector:

it('should toggle menu', () => {
  const fixture = TestBed.createComponent(TestComponent);
  const debugElement = fixture.debugElement.query(By.directive(ToggleDirective));
  const directive = debugElement.injector.get(ToggleDirective)
  expect(directive.visible).toBeFalsy();
  directive.onVoidClick();
  expect(directive.visible).toBeTruthy();
});
like image 87
Matthew Leffler Avatar answered Oct 13 '22 18:10

Matthew Leffler