Почему не запускается вызов обработчика триггера EventHandler? - PullRequest
0 голосов
/ 24 апреля 2020

У меня есть компонент:

import { Component, HostBinding, Input, OnChanges, SimpleChanges } from '@angular/core';
import { animate, state, style, transition, trigger } from '@angular/animations';

@Component({
  selector: 'app-card',
  templateUrl: 'card.component.html',
  styleUrls: ['card.component.scss'],
})
export class CardComponent implements OnChanges {
  @Input()
  isNew = false;

  @Input()
  @HostBinding('class.expanded')
  expanded: boolean;

  @Input()
  header: string;

  ngOnChanges(changes: SimpleChanges): void {
    if ('isNew' in changes && this.isNew === true) {
      this.expanded = true;
    }
  }

  onClick(): void {
    console.log('onClick');
    if (this.isNew) {
      return;
    }

    this.expanded = !this.expanded;
  }

  onContentClick(e: MouseEvent): void {
    e.stopPropagation();
  }
}

и шаблон:

<mat-card (click)="onClick()">
  <div class="header">
    <span class="header-text">{{ header }}</span>
    <button *ngIf="!isNew" mat-icon-button>
      <mat-icon>expand_more</mat-icon>
    </button>
  </div>
  <mat-card-content *ngIf="expanded"
                    (click)="onContentClick($event)">
  </mat-card-content>
</mat-card>

Я пытаюсь написать модульные тесты для тестирования этого компонента, поэтому есть тест:

import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { Component, DebugElement, NO_ERRORS_SCHEMA, ViewChild } from '@angular/core';
import { By } from '@angular/platform-browser';
import { CardComponent } from './card.component';
import { MatCardModule } from '@angular/material/card';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';

@Component({
  template: '<app-card header="Some header"><div class="content">Content text</div></app-card>',
  styles: ['.content { height: 100px }'],
})
class CardWrapperComponent {
  @ViewChild(CardComponent)
  card: CardComponent;
}

describe('CardComponent', () => {
  let wrapper: CardWrapperComponent;
  let card: CardComponent;
  let fixture: ComponentFixture<CardWrapperComponent>;
  let de: DebugElement;

  beforeEach(async () => {
    fixture = TestBed.configureTestingModule({
      imports: [
        NoopAnimationsModule,
        MatCardModule,
        MatButtonModule,
        MatIconModule,
      ],
      declarations: [
        CardWrapperComponent,
        CardComponent,
      ],
      schemas: [
        NO_ERRORS_SCHEMA,
      ],
    }).createComponent(CardWrapperComponent);

    wrapper = fixture.componentInstance;

    await fixture.detectChanges();

    card = wrapper.card;
    de = fixture.debugElement.query(By.directive(CardComponent));
  });

  it('should display a header', () => {
    expect(de.nativeElement.textContent).toContain('Some header');
  });

  it('should not display content', () => {
    expect(de.nativeElement.textContent).not.toContain('Content text');
  });

  fdescribe('when expand button is clicked', () => {
    beforeEach(async () => {
      const expandButton = de.query(By.css('button'));
      expandButton.triggerEventHandler('click', undefined);
      // expandButton.nativeElement.click();

      await fixture.detectChanges();
    });

    fit('should be expanded', () => {
      expect(de.nativeElement.offsetHeight).toBe(140);
    });
  });
});

, и есть проблема, что expandButton.triggerEventHandler('click', undefined); не запускает обработчик onClick. Если я использую expandButton.nativeElement.click();, все работает хорошо.

Я не могу понять, почему это не работает. В связи с этим возникает вопрос: почему мы должны использовать абстракцию DebugElement, если она вызывает проблемы? В чем выгода? Так как модульные тесты не так просты и требуют много глубоких знаний, иногда на создание модульного теста требуется больше времени, чем на саму функциональность. Я думал, что инструменты должны облегчать и сокращать затраченное время Я вижу обратный случай, и мне нужно задать вопрос здесь, потому что случай для меня совершенно неясен.

Заранее спасибо!

...