Тестирование изменения размера окна в директиве Angular - размеры окна не определены после события изменения размера

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

import {Directive, ElementRef, Renderer2, HostListener} from '@angular/core';


@Directive({selector: '[fittext]'})
export class FittextDirective {

  constructor(private element: ElementRef, private renderer: Renderer2) { }

  public changeFontSize(): void {
    const htmlElement: HTMLElement = this.element.nativeElement;
    const elemDims = htmlElement.getBoundingClientRect();
    const height = elemDims.height;
    // Set new font size on element
    this.renderer.setStyle(htmlElement, 'font-size', `${height / 2}px`);
  }

  @HostListener('window:resize')
  public onResize(): void {
    this.changeFontSize();
  }

}

И я пытаюсь протестировать его, используя пользовательский компонент-оболочку и отправляя событие изменения размера в окно.

import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { FittextDirective } from './fittext.directive';
import { Component, ViewChild, ElementRef } from '@angular/core';
import { By } from '@angular/platform-browser';


@Component({
  template: `
    <div #div fittext>{{ text }}</div>
    <style>
      div {
        height: 100vh;
        width: 100vw;
        font-size: 100%;
      }
    </style>
  `
})
class TestComponent {
  @ViewChild('div') div: ElementRef;
  public text: string = 'This is test string';
}


describe('FittextDirective', () => {
  let component: TestComponent;
  let fixture: ComponentFixture<TestComponent>;

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

  beforeEach(() => {
    fixture = TestBed.createComponent(TestComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  fit('should trigger on resize', () => {
    const {height, width} = component.div.nativeElement.getBoundingClientRect();
    const fontSize = component.div.nativeElement.style.fontSize;
    window.dispatchEvent(new Event('resize'));
    fixture.detectChanges()

    const resizedElement = fixture.debugElement.query(By.directive(FittextDirective));
    const {newHeight, newWidth} = resizedElement.nativeElement.getBoundingClientRect();
    const newFontSize = resizedElement.nativeElement.style.fontSize;

    expect(newHeight).not.toEqual(height);
    expect(newWidth).not.toEqual(width);
    expect(newFontSize).not.toEqual(fontSize);
  });
});

Однако тесты сообщают, что размеры шрифта равны '', а высота и ширина после изменения размера (т. е. newHeight и newWidth) равны undefined. Почему размер шрифта представляет собой пустую строку, хотя размер шрифта должен соответствовать размеру div? И почему высота и ширина после изменения размера окна не определены? Я использую безголовый хром для тестирования, поэтому я не могу использовать метод window.resizeTo(width, height).

Изменить 1: по предложению Alex K я изменил newHeight и newWidth на:

const newHeight = resizedElement.nativeElement.getBoundingClientRect().height;
const newWidth = resizedElement.nativeElement.getBoundingClientRect().width;

Однако кажется, что после события изменения размера размер окна не изменяется (я получаю ошибку Expected 600 not to equal 600. и Expected 785 not to equal 785.). Я также изменил стиль между тегами на стиль в атрибуте компонента, то есть на атрибут styles, но, тем не менее, fontSize сообщается как '' (или любой стиль в этом отношении).

Изменить 2: по какой-то странной причине стили можно получить только с помощью window.getComputedStyle() (см. это). Теперь я получаю размер шрифта, но он не меняется после изменения размера.

const styles = window.getComputedStyle(element.nativeElement);
const fontSize = styles.fontSize;
...
const newStyles = window.getComputedStyle(resizedElement.nativeElement);
const newFontSize = newStyles.fontSize;

Редактировать 3: Как и предполагалось, я подделал размеры с помощью spyOn, однако это не изменяет размер шрифтов.

spyOn(component.div.nativeElement, 'getBoundingClientRect')
  .and.returnValue({height: height / 2, width: width / 2});

window.dispatchEvent(new Event('resize'));
fixture.detectChanges()

person Gitnik    schedule 20.02.2019    source источник
comment
const {newHeight, newWidth} = resizedElement.nativeElement.getBoundingClientRect(); дает undefined, потому что он пытается прочитать свойства с именами newHeight и newWidth, которые не существуют в объекте. Вам нужно прочитать свойства height и width.   -  person Alex K    schedule 20.02.2019
comment
Не уверен, как безголовый Chrome обрабатывает такие вещи, как getBoundingClientRect(). Но вы можете использовать jasmine.spyOn, чтобы метод возвращал любые размеры, которые вы хотите. Таким образом, вы можете вернуть 1000 для высоты, а затем проверить, например, что размер шрифта составляет 500 пикселей.   -  person Alex K    schedule 20.02.2019
comment
@AlexK спасибо, я обновил код. Проблема со шпионажем в том, что я всегда получаю пустую строку для любого стиля, который я устанавливаю, так что мне нечего шпионить. И я не могу напрямую шпионить за директивными методами, потому что он обернут тестовым компонентом.   -  person Gitnik    schedule 20.02.2019
comment
Вы запускаете фальшивое событие изменения размера окна, но размер окна на самом деле не меняется. Таким образом, размеры div вашей директивы также не изменятся. Но вы можете подделать его до того, как вызовете событие изменения размера: spyOn(component.div.nativeElement, 'getBoundingClientRect').and.returnValue({height: 100, width: 200})   -  person Alex K    schedule 20.02.2019
comment
@AlexK Спасибо. Это решает проблемы с размерами. Но поскольку это похоже на поддельное событие изменения размера окна, размер шрифта не меняется. :(   -  person Gitnik    schedule 21.02.2019