簡體   English   中英

Jasmine 測試中 AfterViewInit 的生命周期鈎子

[英]Lifecycle hook of AfterViewInit in Jasmine test

我對與 Jasmine 測試相關的生命周期掛鈎感到困惑。 LifeCycle Angular 文檔沒有提到測試https://angular.io/guide/lifecycle-hooks 測試文檔只提到 OnChange https://angular.io/guide/testing 我有一個示例組件如下:

import { Component, OnInit, AfterViewInit, OnDestroy, ElementRef } from '@angular/core';
...
@Component({
  selector: 'app-prod-category-detail',
  templateUrl: './prod-category-detail.component.html',
  styleUrls: ['./prod-category-detail.component.css']
})
//
export class ProdCategoryDetailComponent implements OnInit, AfterViewInit, OnDestroy {
    ...
    nav: HTMLSelectElement;
    //
    constructor(
        ...
        private _elementRef: ElementRef ) { }
    ...
    ngAfterViewInit() {
        console.log( 'ProdCategoryDetailComponent: ngAfterViewInit' );
        this.nav = this._elementRef.nativeElement.querySelector('#nav');
    }
    ...
}

請注意,這是一個具有最新下載的 Angular CLI 應用程序。 在 Karma 中,我看不到控制台日志,因此從不設置導航 我目前在我的規范中調用它如下:

beforeEach(() => {
  fixture = TestBed.createComponent(ProdCategoryDetailComponent);
  sut = fixture.componentInstance;
  sut.ngAfterViewInit( );
  fixture.detectChanges( );
});

這是處理這個問題的正確方法嗎?

對於 shusson 來說,這是前一段時間,我已經有一段時間沒有看過了。 希望它會有所幫助。 注意,我使用的是 Primeface primeng 庫:

describe('ProdCategoryDetailComponent', () => {
  let sut: ProdCategoryDetailComponent;
  let fixture: ComponentFixture< ProdCategoryDetailComponent >;
  let alertService: AlertsService;
  let prodCatService: ProdCategoryServiceMock;
  let confirmService: ConfirmationServiceMock;
  let elementRef: MockElementRef;
  //
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        FormsModule,
        ButtonModule,
        BrowserAnimationsModule
      ],
      declarations: [
        ProdCategoryDetailComponent,
        AlertsComponent,
        ConfirmDialog
      ],
      providers: [
        AlertsService,
        { provide: ProdCategoryService, useClass: ProdCategoryServiceMock },
        { provide: MockBackend, useClass: MockBackend },
        { provide: BaseRequestOptions, useClass: BaseRequestOptions },
        { provide: ConfirmationService, useClass: ConfirmationServiceMock },
        { provide: ElementRef, useClass: MockElementRef }
      ]
    })
    .compileComponents();
  }));
  //
  beforeEach(inject([AlertsService, ProdCategoryService,
      ConfirmationService, ElementRef],
        (srvc: AlertsService, pcsm: ProdCategoryServiceMock,
        cs: ConfirmationServiceMock, er: MockElementRef) => {
    alertService = srvc;
    prodCatService = pcsm;
    confirmService = cs;
    elementRef = er;
  }));
  //
  beforeEach(() => {
    fixture = TestBed.createComponent(ProdCategoryDetailComponent);
    sut = fixture.componentInstance;
    sut.ngAfterViewInit( );
    fixture.detectChanges( );
  });
  //

我經常在必要時直接調用每個規范的生命周期鈎子。 這很有效。 因為這樣可以在調用ngAfterViewInit()ngOnInit()之前靈活地操作任何數據。

我也看到過幾個角度庫測試規范以相同的方式使用它。 例如,檢查此視頻規范文件。 因此手動調用這些方法沒有壞處。

此處也復制相同的代碼,以避免將來破壞鏈接。

it('Should hide controls after view init', () => {
        spyOn(controls, 'hide').and.callFake(() => {});

        controls.vgAutohide = true;

        controls.ngAfterViewInit();

        expect(controls.hide).toHaveBeenCalled();
});

我們不能直接從規范調用生命周期鈎子,但我們可以調用自定義方法。 因為為了調用生命周期書籍,我們需要使用夾具創建組件的實例。

示例:在我的示例中,我需要將 padding-left 和 right 設置為 0,因為默認情況下引導程序會向左和向右提供一些填充所以我需要將其刪除。

HTML 文件 - app.component.ts

import { Component, ViewChild, ElementRef, Renderer2 } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  @ViewChild('navCol', { static: true }) navCol: ElementRef;

  constructor(private renderer: Renderer2) {  }

  ngAfterViewInit() {
    this.renderer.setStyle(this.navCol.nativeElement, 'padding-left', '0px');
    this.renderer.setStyle(this.navCol.nativeElement, 'padding-right', '0px');
  }
}

app.component.spec.ts

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

describe('AppComponent', () => {
  it('should load page and remove padding', () => {
    const fixture = TestBed.createComponent(AppComponent);
    fixture.componentInstance.ngAfterViewInit();
    const styles = window.getComputedStyle(fixture.nativeElement);

    expect(styles.paddingLeft).toBe('0px');
    expect(styles.paddingRight).toBe('0px');
  });
});

暫無
暫無

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

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