簡體   English   中英

Angular 5中的HostListener滾動測試

[英]HostListener scroll testing in Angular 5

如何在Angular 5中測試滾動? 如何在測試中模擬窗口?

這是我的代碼:

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

@Directive({
  selector: '[escElementPreventOverlap]'
})
export class ElementPreventOverlapDirective {
  private offsetTop: number;
  private scrollTop: number;

  constructor(private element: ElementRef) {
  }

  @HostListener('window:scroll', ['$event'])
  @HostListener('window:resize', ['$event'])
  event(event) {
    this.offsetTop= this.element.nativeElement.parentElement.offsetTop + this.element.nativeElement.parentElement.offsetHeight;
    this.scrollTop= document.documentElement.scrollTop + window.innerHeight;

    if (this.scrollTop> this.offsetTop) {
      this.element.nativeElement.classList.remove('fixed');
    } else {
      this.element.nativeElement.classList.add('fixed');
    }
  }
}

工作正常,但我不知道如何測試。

我發現了該怎么做! 您需要將窗口注入到使用它的位置,以便在測試期間可以對其進行模擬。

首先,您必須創建一個文件(options.ts),並編寫以下代碼:

import { InjectionToken } from '@angular/core';

export const N_DOCUMENT = new InjectionToken<Document>('DocumentToken');
export const N_WINDOW = new InjectionToken<Window>('WindowToken');

其次,您必須在指令/組件中注入窗口:

import { Directive, ElementRef, HostListener, Inject } from '@angular/core';
import { N_WINDOW, N_DOCUMENT } from '../options';

@Directive({
  selector: '[appElement]'
})
export class ElementDirective {
  parentOffsetTopWithHeight: number;
  documentScrollTopWithHeight: number;

  constructor(public element: ElementRef, @Inject(N_WINDOW) window, @Inject(N_DOCUMENT) document) {
  }
 @HostListener('window:scroll', ['$event'])
  scroll(event) {...}
    }

第三,您可以在類似的測試中使用它:

import { ElementRef } from '@angular/core';
import { TestBed } from '@angular/core/testing';

import { ElementDirective } from '../element.directive';
import { N_WINDOW, N_DOCUMENT } from '../options';


class ElementRefMock extends ElementRef {
  nativeElement = {
    parentElement: {
      offsetTop: 1200,
      offsetHeight: 200,
    },
    classList: {
      list: [],
      add (className) {
        if (this.list.indexOf(className) === -1) {
          this.list.push(className);
        }
      },
      remove (className) {
        const classIndex = this.list.indexOf(className);
        if (classIndex !== -1) {
          this.list.splice(classIndex, 1);
        }
      },
      contains (className) {
        return this.list.indexOf(className) !== -1;
      }
    }
      };

      setNativeElement(nativeElement) {
        this.nativeElement = nativeElement;
      }
    }

    describe('ElementDirective', () => {
      let directive: ElementDirective;
      const elemDom = document.createElement('div');
      const elementRef = new ElementRefMock(elemDom);

      beforeEach(() => {
        TestBed.configureTestingModule({
          providers: [
            {provide: N_WINDOW, useValue: window},
            {provide: N_DOCUMENT, useValue: document}
          ],
        });
        directive = new ElementDirective(elementRef, window, document);
      });

      it('should create an instance', () => {
        expect(directive).toBeTruthy();
      });

      describe('scroll', () => {

        it('should add class position-fixed', () => {
          spyOnProperty(window, 'innerHeight', 'get').and.returnValue(1000);
          spyOnProperty(document.documentElement, 'scrollTop', 'get').and.returnValue(100);
          directive.scroll(<any>{});
          expect(directive.element.nativeElement.classList.contains('position-fixed')).toBe(true);
        });
    });

第四,必須在module.ts中將提供程序添加到NgModule:

import { DOCUMENT } from '@angular/common';
import { N_WINDOW, N_DOCUMENT } from '../options';

export function nWindowFactory() {
  return window;
}

@NgModule({
...
  providers: [
    {provide: N_WINDOW, useFactory: nWindowFactory},
    {provide: N_DOCUMENT, useExisting: DOCUMENT}
  ]
})

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM