Угловой 7: Как лучше всего передать правильные данные структурной директиве? - PullRequest
0 голосов
/ 11 марта 2019

Я пишу юнит-тесты для приложения Angular , в котором используются Angular Material Components . И я застрял с тестированием компонента, который использует Таблица материалов надлежащим образом, потому что он имеет структурные директивы , как показано ниже.

<mat-table [dataSource]="classifications$ | async">
  <mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></mat-header-row>
</mat-table>

Я искал в Интернете и StackOverflow, чтобы найти лучший способ справиться с ним, как вы можете с обычными директивами и компонентами, для которых вы можете получить ComponentInstance, но я не нашел способ сделать это с структурным директивы . Поэтому, чтобы разблокировать мой билет, я пришел к этому хакерскому решению, чтобы иметь объект context, который будет контейнером для того, что устанавливается в структурной директиве .

Мне также нужно вызвать this.viewContainer.createEmbeddedView(this.templateRef); в структурной директиве , чтобы получить визуализированный компонент, потому что я также хочу утверждать , что он присутствует в шаблоне.

Если вы знаете лучший способ, пожалуйста, покажите мне путь;) Заранее спасибо!

Ниже вы можете увидеть мой текущий тест:

import { Component, Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';

const context: any = {};

@Directive({ selector: '[appShow]' })
export class ShowDirective {
  constructor(
    private templateRef: TemplateRef<any>,
    private viewContainer: ViewContainerRef,
  ) {}

  @Input() set appShow(show: boolean) {
    context.show = show;

    this.viewContainer.createEmbeddedView(this.templateRef);
  }
}

@Component({
  template: `
    <h1>STRUCTURAL DIRECTIVE TEST displayExtraHeader: {{displayExtraHeader}}</h1>
    <h2 *appShow="displayExtraHeader">Lorem ipsum</h2>
  `,
})
class StructuralDirectiveComponent {
  displayExtraHeader = true;
}

describe('Structural Directive', () => {
  let component: StructuralDirectiveComponent;
  let fixture: ComponentFixture<StructuralDirectiveComponent>;
  let compiled: any;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
        ShowDirective,
        StructuralDirectiveComponent,
      ],
    })
      .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(StructuralDirectiveComponent);
    compiled = fixture.debugElement.nativeElement;
    component = fixture.componentInstance;
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });

  describe('HTML', () => {
    beforeEach(() => {
      delete context.show;
      component.displayExtraHeader = false;
      fixture.detectChanges();
    });

    it('should render <h1>', () => {
      expect(compiled.querySelector('h1')).not.toBeNull();
    });
    it('should pass displayExtraHeader to appShow', () => {
      const directive1: any = fixture.debugElement.query(By.css('[appShow]'));
      const directive2: any = fixture.debugElement.query(By.directive(ShowDirective));

      console.log(`>>> directive1`, directive1);
      console.log(`>>> directive2`, directive2);

      // directive1 and directive 2 are null
      // @TODO: how to get an instance of structural directive?

      expect(context.show).toEqual(false);
    });
  });
});
...