首页 > 解决方案 > 在 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();
  }

}

我正在尝试使用自定义包装器组件并通过在窗口上调度 resize 事件来测试它。

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);
  });
});

但是,测试报告字体大小为'',调整大小(即newHeightnewWidth)后的高度和宽度为undefined。为什么字体大小是空字符串,即使字体大小应该与 div 匹配?为什么窗口调整大小后的高度和宽度未定义?我正在使用无头 chrome 进行测试,所以我不能使用window.resizeTo(width, height)方法。

编辑1:经过我的建议,Alex K我改变newHeightnewWidth

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()

标签: angularjasmineangular-directiveangular-test

解决方案


推荐阅读