Angular 測試工具API

2022-07-08 09:41 更新

測試實用工具 API

本頁面描述了一些最有用的 Angular 測試特性。

Angular 測試實用工具包括 ?TestBed?、?ComponentFixture ?以及一些控制測試環(huán)境的函數(shù)。?TestBed ?和 ?ComponentFixture ?類是單獨介紹的。

下面是一些獨立函數(shù)的摘要,以使用頻率排序:

函數(shù)

詳情

waitForAsync

在一個特殊的async 測試區(qū)域中運行測試(?it?)的函數(shù)體或準備函數(shù)(?beforeEach?)。

fakeAsync

在一個特殊的fakeAsync 測試區(qū)域中運行測試(?it?)的函數(shù)體,以便啟用線性風格的控制流。

tick

通過在 fakeAsync 測試區(qū)域中刷新定時器和微任務(wù)(micro-task)隊列來仿真時間的流逝以及異步活動的完成。

好奇和執(zhí)著的讀者可能會喜歡這篇長博客:
Tasks, microtasks, queues and schedules

接受一個可選參數(shù),它可以把虛擬時鐘往前推進特定的微秒數(shù)。清除調(diào)度到那個時間幀中的異步活動。

inject

從當前的 TestBed 注入器中把一個或多個服務(wù)注入到一個測試函數(shù)中。它不能用于注入組件自身提供的服務(wù)。

discardPeriodicTasks 當 ?fakeAsync ?測試程序以正在運行的計時器事件任務(wù)(排隊中的 ?setTimeOut ?和 ?setInterval ?的回調(diào))結(jié)束時,測試會失敗,并顯示一條明確的錯誤信息。
一般來講,測試程序應(yīng)該以無排隊任務(wù)結(jié)束。當待執(zhí)行計時器任務(wù)存在時,調(diào)用 ?discardPeriodicTasks ?來觸發(fā)任務(wù)隊列,防止該錯誤發(fā)生。
flushMicrotasks

當 ?fakeAsync ?測試程序以待執(zhí)行微任務(wù)(比如未解析的承諾)結(jié)束時,測試會失敗并顯示明確的錯誤信息。

一般來說,測試應(yīng)該等待微任務(wù)結(jié)束。當待執(zhí)行微任務(wù)存在時,調(diào)用 ?flushMicrotasks ?來觸發(fā)微任務(wù)隊列,防止該錯誤發(fā)生。

ComponentFixtureAutoDetect

一個服務(wù)提供者令牌,用于開啟自動變更檢測。

getTestBed 獲取當前 ?TestBed ?實例。通常用不上,因為 ?TestBed ?的靜態(tài)類方法已經(jīng)夠用。?TestBed ?實例有一些很少需要用到的方法,它們沒有對應(yīng)的靜態(tài)方法。

TestBed 類摘要

?TestBed ?類是 Angular 測試工具的主要類之一。它的 API 很龐大,可能有點過于復(fù)雜,直到你一點一點的探索它們。

傳給 ?configureTestingModule ?的模塊定義是 ?@NgModule? 元數(shù)據(jù)屬性的子集。

type TestModuleMetadata = {
  providers?: any[];
  declarations?: any[];
  imports?: any[];
  schemas?: Array<SchemaMetadata | any[]>;
};

每一個重載方法接受一個 ?MetadataOverride<T>?,這里 ?T? 是適合這個方法的元數(shù)據(jù)類型,也就是 ?@NgModule?、?@Component?、?@Directive? 或者 ?@Pipe? 的參數(shù)。

type MetadataOverride<T> = {
  add?: Partial<T>;
  remove?: Partial<T>;
  set?: Partial<T>;
};

?TestBed ?的 API 包含了一系列靜態(tài)類方法,它們更新或者引用全局的 ?TestBed ?實例。

在內(nèi)部,所有靜態(tài)方法在 ?getTestBed()? 函數(shù)返回的當前運行時間的 ?TestBed ?實例上都有對應(yīng)的方法。

在 ?BeforeEach()? 內(nèi)調(diào)用 ?TestBed ?方法,以確保在運行每個單獨測試時,都有嶄新的開始。

這里列出了最重要的靜態(tài)方法,以使用頻率排序。

方法

詳情

configureTestingModule

測試墊片(karma-test-shimbrowser-test-shim)創(chuàng)建了初始測試環(huán)境和默認測試模塊。默認測試模塊是使用基本聲明和一些 Angular 服務(wù)替代品,它們是所有測試程序都需要的。
調(diào)用 configureTestingModule 來為一套特定的測試定義測試模塊配置,添加和刪除導(dǎo)入、(組件、指令和管道的)聲明和服務(wù)提供者。

compileComponents

在配置好測試模塊之后,異步編譯它。如果測試模塊中的任何一個組件具有 templateUrl 或 styleUrls,那么你必須調(diào)用這個方法,因為獲取組件的模板或樣式文件必須是異步的。
調(diào)用完 compileComponents 之后,TestBed 的配置就會在當前測試期間被凍結(jié)。

createComponent<T>

基于當前 TestBed 的配置創(chuàng)建一個類型為 T 的組件實例。調(diào)用 createComponent 之后,TestBed 的配置就會在當前測試期間被凍結(jié)。

overrideModule

替換指定的 NgModule 的元數(shù)據(jù)?;叵胍幌?,模塊可以導(dǎo)入其它模塊。overrideModule 方法可以深入到當前測試模塊深處,修改其中一個內(nèi)部模塊。

overrideComponent

替換指定組件類的元數(shù)據(jù),該組件類可能嵌套在一個很深的內(nèi)部模塊中。

overrideDirective

替換指定指令類的元數(shù)據(jù),該指令可能嵌套在一個很深的內(nèi)部模塊中。

overridePipe

替換指定管道類的元數(shù)據(jù),該管道可能嵌套在一個很深的內(nèi)部模塊中。

inject

從當前 TestBed 注入器獲取一個服務(wù)。inject 函數(shù)通常都能勝任這項工作,但是如果它沒法提供該服務(wù)時就會拋出一個異常。
如果該服務(wù)是可選的呢?
TestBed.inject() 方法可以接受可選的第二參數(shù),當 Angular 找不到指定的服務(wù)提供者時,就會返回該對象(下面這個例子中是 null):

expect(TestBed.inject(NotProvided, null)).toBeNull();
調(diào)用了 TestBed.inject 之后然后通過調(diào)用,TestBed 的配置就會在當前測試期間被凍結(jié)。
initTestEnvironment

為整套測試的運行初始化測試環(huán)境。
測試墊片(karma-test-shimbrowser-test-shim)會為你調(diào)用它,所以你很少需要自己調(diào)用它。
這個方法只能被調(diào)用一次。如果確實需要在測試程序運行期間改變這個默認設(shè)置,那么先調(diào)用 resetTestEnvironment。
指定 Angular 編譯器工廠,PlatformRef,和默認 Angular 測試模塊。以 @angular/platform-<platform_name>/testing/<platform_name> 的形式提供非瀏覽器平臺的替代品。

resetTestEnvironment

重設(shè)初始測試環(huán)境,包括默認測試模塊在內(nèi)。

少數(shù) ?TestBed ?實例方法沒有對應(yīng)的靜態(tài)方法。它們很少被使用。

ComponentFixture 類

?TestBed.createComponent<T>? 會創(chuàng)建一個組件 ?T? 的實例,并為該組件返回一個強類型的 ?ComponentFixture?。

?ComponentFixture ?的屬性和方法提供了對組件、它的 DOM 和它的 Angular 環(huán)境方面的訪問。

ComponentFixture 的屬性

下面是對測試最重要的屬性,以使用頻率排序。

屬性

詳情

componentInstance

被 TestBed.createComponent 創(chuàng)建的組件類實例。

debugElement

與組件根元素關(guān)聯(lián)的 DebugElement。
debugElement 提供了在測試和調(diào)試期間深入探查組件及其 DOM 元素的功能。它對于測試者是一個極其重要的屬性。

nativeElement

組件的原生根 DOM 元素。

changeDetectorRef

組件的 ChangeDetectorRef。
在測試一個擁有 ChangeDetectionStrategy.OnPush 的組件,或者在組件的變化測試在你的程序控制下時,ChangeDetectorRef 是最重要的。

ComponentFixture 方法

fixture 方法使 Angular 對組件樹執(zhí)行某些任務(wù)。在觸發(fā) Angular 行為來模擬的用戶行為時,調(diào)用這些方法。

下面是對測試最有用的方法。

方法

詳情

detectChanges

為組件觸發(fā)一輪變化檢查。
調(diào)用它來初始化組件(它調(diào)用 ngOnInit)?;蛘咴谀愕臏y試代碼改變了組件的數(shù)據(jù)綁定屬性值后調(diào)用它。Angular 不能檢測到你已經(jīng)改變了 personComponent.name 屬性,也不會更新 name 的綁定,直到你調(diào)用了 detectChanges。
之后,運行 checkNoChanges,來確認沒有循環(huán)更新,除非它被這樣調(diào)用:detectChanges(false)

autoDetectChanges

如果你希望這個夾具自動檢測變更,就把這個設(shè)置為 true。
當自動檢測打開時,測試 fixture 監(jiān)聽 zone 事件,并調(diào)用 detectChanges。當你的測試代碼直接修改了組件屬性值時,你還是要調(diào)用 fixture.detectChanges 來觸發(fā)數(shù)據(jù)綁定更新。
默認值是 false,喜歡對測試行為進行精細控制的測試者一般保持它為 false。

checkNoChanges

運行一次變更檢測來確認沒有待處理的變化。如果有未處理的變化,它將拋出一個錯誤。

isStable

如果 fixture 當前是穩(wěn)定的,則返回 true。如果有異步任務(wù)沒有完成,則返回 false。

whenStable

返回一個承諾,在 fixture 穩(wěn)定時解析。
要想在完成了異步活動或異步變更檢測之后再繼續(xù)測試,可以對那個承諾對象進行掛鉤。

destroy

觸發(fā)組件的銷毀。

DebugElement

?DebugElement ?提供了對組件的 DOM 的訪問。

?fixture.debugElement? 返回測試根組件的 ?DebugElement?,通過它你可以訪問(查詢)fixture 的整個元素和組件子樹。

下面是 ?DebugElement ?最有用的成員,以使用頻率排序。

成員

詳情

nativeElement

與瀏覽器中 DOM 元素對應(yīng)(WebWorkers 時,值為 null)。

query

調(diào)用 query(predicate: Predicate<DebugElement>) 會在子樹的任意深度中查找并返回能和謂詞函數(shù)匹配的第一個 DebugElement。

queryAll

調(diào)用 queryAll(predicate: Predicate<DebugElement>) 會在子樹的任意深度中查找能和謂詞函數(shù)匹配的所有 DebugElement。

injector

宿主依賴注入器。比如,根元素的組件實例注入器。

componentInstance

元素自己的組件實例(如果有)。

context

為元素提供父級上下文的對象。通常是控制該元素的祖級組件實例。
當一個元素被 *ngFor 重復(fù),它的上下文為 NgForOf,它的 $implicit 屬性值是該行的實例值。比如,*ngFor="let hero of heroes" 里的 hero。

children

DebugElement 的直接子元素??梢酝ㄟ^繼續(xù)深入 children 來遍歷這棵樹。

?DebugElement ?還有 ?childNodes?,即 ?DebugNode ?對象列表。?DebugElement ?從 ?DebugNode ?對象衍生,而且通常節(jié)點(node)比元素多。測試者通常忽略普通節(jié)點。

parent

DebugElement 的父級。如果 DebugElement 是根元素,parent 為 null。

name

元素的標簽名字,如果它是一個元素的話。

triggerEventHandler

如果在該元素的 listeners 集合中有相應(yīng)的監(jiān)聽器,就根據(jù)名字觸發(fā)這個事件。第二個參數(shù)是該處理器函數(shù)所需的事件對象。
如果事件缺乏監(jiān)聽器,或者有其它問題,考慮調(diào)用 nativeElement.dispatchEvent(eventObject)。

listeners

元素的 @Output 屬性以及/或者元素的事件屬性所附帶的回調(diào)函數(shù)。

providerTokens

組件注入器的查詢令牌。包括組件自己的令牌和組件的 providers 元數(shù)據(jù)中列出來的令牌。

source

source 是在源組件模板中查詢這個元素的處所。

references

與模板本地變量(比如 #foo)關(guān)聯(lián)的詞典對象,關(guān)鍵字與本地變量名字配對。

?DebugElement.query(predicate)? 和 ?DebugElement.queryAll(predicate)? 方法接受一個條件方法,它過濾源元素的子樹,返回匹配的 ?DebugElement?。

這個條件方法是任何接受一個 ?DebugElement ?并返回真值的方法。下面的例子查詢所有擁有名為 ?content ?的模塊本地變量的所有 ?DebugElement?:

// Filter for DebugElements with a #content reference
const contentRefs = el.queryAll( de => de.references['content']);

Angular 的 ?By ?類為常用條件方法提供了三個靜態(tài)方法:

靜態(tài)方法

詳情

By.all

返回所有元素

By.css(selector)

返回符合 CSS 選擇器的元素

By.directive(directive)

返回 Angular 能匹配一個指令類實例的所有元素

// Can find DebugElement either by css selector or by directive
const h2 = fixture.debugElement.query(By.css('h2'));
const directive = fixture.debugElement.query(By.directive(HighlightDirective));


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號