新聞中心
測試屬性型指令
屬性型指令會修改元素、組件或其他指令的行為。它的名字反映了該指令的應用方式:作為宿主元素的一個屬性。

如果你要試驗本指南中所講的應用,請在瀏覽器中運行它或下載并在本地運行它。
測試 HighlightDirective
本范例應用的 ?HighlightDirective ?會根據(jù)數(shù)據(jù)綁定中的顏色或默認顏色(淺灰)來設置元素的背景色。它還會把該元素的自定義屬性(?customProperty?)設置為 ?true?,當然這除了示范本技術之外別無它用。
import { Directive, ElementRef, Input, OnChanges } from '@Angular/core';
@Directive({ selector: '[highlight]' })
/**
* Set backgroundColor for the attached element to highlight color
* and set the element's customProperty to true
*/
export class HighlightDirective implements OnChanges {
defaultColor = 'rgb(211, 211, 211)'; // lightgray
@Input('highlight') bgColor = '';
constructor(private el: ElementRef) {
el.nativeElement.style.customProperty = true;
}
ngOnChanges() {
this.el.nativeElement.style.backgroundColor = this.bgColor || this.defaultColor;
}
}它在整個應用中都用到過,也許最簡單的是在 ?AboutComponent ?中:
import { Component } from '@angular/core';
@Component({
template: `
About
Quote of the day:
`
})
export class AboutComponent { }要想在 ?AboutComponent ?中測試 ?HighlightDirective ?的特定用法,只需要瀏覽組件測試場景中的“嵌套組件測試”一節(jié)中提到的各種技巧。
beforeEach(() => {
fixture = TestBed.configureTestingModule({
declarations: [ AboutComponent, HighlightDirective ],
schemas: [ CUSTOM_ELEMENTS_SCHEMA ]
})
.createComponent(AboutComponent);
fixture.detectChanges(); // initial binding
});
it('should have skyblue ', () => {
const h2: HTMLElement = fixture.nativeElement.querySelector('h2');
const bgColor = h2.style.backgroundColor;
expect(bgColor).toBe('skyblue');
});
但是,測試單個用例不太可能涉及指令的全部能力。要找到并測試那些使用了該指令的所有組件會很乏味、很脆弱,而且?guī)缀醪豢赡茏龅酵耆采w。
純類測試可能會有一點幫助,但像這種屬性型指令往往會操縱 DOM。孤立的單元測試不會觸及 DOM,因此也無法給人帶來對指令功效的信心。
更好的解決方案是創(chuàng)建一個人工測試組件來演示應用該指令的所有方法。
@Component({
template: `
Something Yellow
The Default (Gray)
No Highlight
`
})
class TestComponent { }這個 ?
? 用例將 ?HighlightDirective?綁定到輸入框中顏色值的名稱。初始值是單詞“cyan”,應該把它設為輸入框的背景顏色。
下面是對該組件的一些測試:
beforeEach(() => {
fixture = TestBed.configureTestingModule({
declarations: [ HighlightDirective, TestComponent ]
})
.createComponent(TestComponent);
fixture.detectChanges(); // initial binding
// all elements with an attached HighlightDirective
des = fixture.debugElement.queryAll(By.directive(HighlightDirective));
// the h2 without the HighlightDirective
bareH2 = fixture.debugElement.query(By.css('h2:not([highlight])'));
});
// color tests
it('should have three highlighted elements', () => {
expect(des.length).toBe(3);
});
it('should color 1st background "yellow"', () => {
const bgColor = des[0].nativeElement.style.backgroundColor;
expect(bgColor).toBe('yellow');
});
it('should color 2nd background w/ default color', () => {
const dir = des[1].injector.get(HighlightDirective) as HighlightDirective;
const bgColor = des[1].nativeElement.style.backgroundColor;
expect(bgColor).toBe(dir.defaultColor);
});
it('should bind background to value color', () => {
// easier to work with nativeElement
const input = des[2].nativeElement as HTMLInputElement;
expect(input.style.backgroundColor)
.withContext('initial backgroundColor')
.toBe('cyan');
input.value = 'green';
// Dispatch a DOM event so that Angular responds to the input value change.
input.dispatchEvent(new Event('input'));
fixture.detectChanges();
expect(input.style.backgroundColor)
.withContext('changed backgroundColor')
.toBe('green');
});
it('bare should not have a customProperty', () => {
expect(bareH2.properties['customProperty']).toBeUndefined();
});
一些技巧值得注意:
- ?
By.directive? 謂詞是一種獲取那些不知道類型但都附有本指令的元素的好辦法。 - ?
By.css('h2:not([highlight])')? 中的 :not偽類可以幫助你找到那些沒有該指令的 ?? 元素。?By.css('*:not([highlight])')? 可以找到?jīng)]有該指令的任意元素。 - ?
DebugElement.styles? 提供了對元素樣式的訪問,即使沒有真正的瀏覽器也是如此,這要歸功于 ?DebugElement?提供的抽象。但是,如果 ?nativeElement?顯得比使用其抽象版本更容易或更清晰,那就把它暴露出來。 - Angular 會在指令宿主元素的注入器中添加上該指令。對默認顏色的測試使用第二個 ?
? 上的注入器來獲取它的 ?HighlightDirective?實例及其 ?defaultColor?。 - ?
DebugElement.properties? 允許訪問本指令設置的自定義屬性。
當前文章:創(chuàng)新互聯(lián)Angular教程:Angular測試屬性型指令
分享URL:http://fisionsoft.com.cn/article/dpiecgc.html


咨詢
建站咨詢
