<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                本節讓我們看看如何使用代碼的方式來完成點擊教師列表的動作,初步的接觸下自動化的魅力。 當前測試用例下,我們需要模擬用戶點擊教師列表,以測試教師列表被點擊后,是否在組件的`@Output`上接收到了相應的值。比如我們模擬點擊教師列表中的最后一個教師: ```typescript +++ b/first-app/src/app/clazz/klass-select/klass-select.component.spec.ts @@ -41,5 +41,10 @@ describe('KlassSelectComponent', () => { fixture.autoDetectChanges(); component.beChange .subscribe((data: number) => console.log('接收到了彈出的數據', data)); + // 模擬點擊教師列表中的第二個教師 }); }); ``` ### 模擬點擊option 在響應式表中,模擬點擊某個`option`僅需要以下兩步: 1. 獲取預點擊`option`對應的值 2. 將值使用`setValue()`方法送入`FormControl` ```typescript @@ -44,6 +42,7 @@ describe('KlassSelectComponent', () => { component.beChange .subscribe((data: number) => console.log('接收到了彈出的數據', data)); // 模擬點擊教師列表中的第二個教師 + const teacher = component.teachers[1]; + console.log(teacher); }); }); ``` 打開控制臺我們得到了一個undefined: ![image-20210325141537067](https://img.kancloud.cn/72/84/7284e1dc5db0f7e5159c3bb1aea068b8_938x156.png) 產生該問題的原因從根上來講是由于JavaScript的異步機制。從當前應用層面上來講,是由于我們的MockApi模擬了真實網絡的延遲。當前對組件的測試大概發生了以下事件: ![image-20210325142503271](https://img.kancloud.cn/7e/dd/7eddccb418d91aa14ae0ede1de08482d_1306x560.png) 如上圖示,由于`MockApi`的延遲發送數據,所以在執行到`const teacher = component.teachers[1];`時,`component.teachers`仍然是個空數組。 ```typescript // 模擬點擊教師列表中的第二個教師 + console.log(component.teachers.length); const teacher = component.teachers[1]; console.log(teacher); ``` ![image-20210325143408038](https://img.kancloud.cn/e6/fb/e6fbfd58b428da84911bc0e6e85bad1c_652x92.png) 但當前我們希望的是單元測試按以下流程執行: ![image-20210325142808204](https://img.kancloud.cn/69/5f/695ff41f6f60e0e8f5c1c77417a4aae2_1350x424.png) ## getTestScheduler() 預使在發生http請求時`MockApi`馬上發送數據,則需要使用`jasmine-marbles`提供的`getTestScheduler()`,該方法的作用是:馬上發送(本計劃延遲發送的)數據 。由于`jasmine-marbles`只被應用在測試環境下,所以我們使用`npm install --save-dev jasmine-marbles`來安裝: ```bash panjie@panjies-Mac-Pro first-app % pwd /Users/panjie/github/mengyunzhi/angular11-guild/first-app panjie@panjies-Mac-Pro first-app % npm install --save-dev jasmine-marbles ... + jasmine-marbles@0.8.1 added 1 package, removed 1 package and audited 1472 packages in 9.079s ... ``` <hr> **以下內容了解即可** 實際上`MockApi`提供了兩種延遲發送數據的方案:`MockApiInterceptor`與`MockApiTestingInterceptor`。`MockApiInterceptor`用于沒有后臺的演示環境,該延遲是通過RxJS的`delay`方法實現的;而`MockApiTestingInterceptor`專門用于測試環境,該延遲是通的RxJS的彈珠來實現的。而彈珠測試的數據發送,是可以通過`jasmine-marbles`手動控制的。 **以下內容了解即可** <hr> 然后我們在當前動態測試模塊下引入支持`jasmine-marbles`馬上發送數據的`MockApiTestingInterceptor`來替換原`MockApiInterceptor`: ```typescript +++ b/first-app/src/app/clazz/klass-select/klass-select.component.spec.ts -import {MockApiInterceptor} from '@yunzhi/ng-mock-api'; +import {MockApiTestingInterceptor} from '@yunzhi/ng-mock-api/testing'; @@ -22,7 +22,7 @@ describe('KlassSelectComponent', () => { providers: [ { provide: HTTP_INTERCEPTORS, multi: true, - useClass: MockApiInterceptor.forRoot([ + useClass: MockApiTestingInterceptor.forRoot([ TeacherMockApi ]) } ``` 接下來便可以在測試代碼中調用`getTestScheduler()`方法來手動控制數據發送了: ```typescript +++ b/first-app/src/app/clazz/klass-select/klass-select.component.spec.ts @@ -5,6 +5,7 @@ import {HTTP_INTERCEPTORS, HttpClientModule} from '@angular/common/http'; import {TeacherMockApi} from '../../mock-api/teacher.mock.api'; import {FormsModule, ReactiveFormsModule} from '@angular/forms'; import {MockApiTestingInterceptor} from '@yunzhi/ng-mock-api/testing'; +import {getTestScheduler} from 'jasmine-marbles'; describe('KlassSelectComponent', () => { let component: KlassSelectComponent; @@ -41,6 +42,10 @@ describe('KlassSelectComponent', () => { fixture.autoDetectChanges(); component.beChange .subscribe((data: number) => console.log('接收到了彈出的數據', data)); + + // 手動控制MockApi發送數據 + getTestScheduler().flush(); + // 模擬點擊教師列表中的第二個教師 console.log(component.teachers.length); ``` ![image-20210325144142916](https://img.kancloud.cn/5b/df/5bdf521b16898577ad7421e40dc7f263_610x82.png) 需要**注意**的是: 1. 這種數據發送方式產生的數據變化并不會被`fixture`感知到,所以如果我們需要查看V層的效果,則需要在數據發送完成后,手動調用`detectChanges()`以使V層重新進行渲染。 2. 引入`MockApiTestingInterceptor`后,在測試中僅當調用`getTestScheduler().flush();`時才會發送數據,否則不會發送數據。 ```typescript +++ b/first-app/src/app/clazz/klass-select/klass-select.component.spec.ts @@ -45,6 +45,7 @@ describe('KlassSelectComponent', () => { // 手動控制MockApi發送數據 getTestScheduler().flush(); + fixture.detectChanges(); // 模擬點擊教師列表中的第二個教師 console.log(component.teachers.length); ``` 此時我們將在V層中將查看到教師列表中的兩個教師。 ### setValue() 最后調用`FormControl`的`setValue()`完成`option`的模擬點擊: ```typescript +++ b/first-app/src/app/clazz/klass-select/klass-select.component.spec.ts @@ -51,5 +51,7 @@ describe('KlassSelectComponent', () => { console.log(component.teachers.length); const teacher = component.teachers[1]; console.log(teacher); + + component.teacherId.setValue(teacher.id); }); }); panjie ``` ![image-20210325144004611](https://img.kancloud.cn/fd/d0/fdd0f75c2b6ac3dcf1b0978225a4ade9_920x154.png) ## 其它方式 我們還可以在單元測試中使用代碼的形式來模擬option的點擊(實際上Angular在select中的option點擊做的并不好),但此方法使用的代碼較多,難度相對較大,實際在生產中我們也很少使用。在這我們僅給出相應的代碼供參考: ```typescript fit('模擬點擊option', () => { expect(component).toBeTruthy(); component.beChange .subscribe((data: number) => console.log('接收到了彈出的數據', data)); // 手動控制MockApi發送數據 getTestScheduler().flush(); fixture.detectChanges(); // 獲取select const htmlSelect = fixture.debugElement.query(By.css('select')).nativeElement as HTMLSelectElement; htmlSelect.click(); // 獲取第二個選項 const htmlOption = htmlSelect.options[1]; // 用該選項的值設置select的值,從而實現模塊點擊 htmlSelect.value = htmlOption.value; // 發送change事件,通知瀏覽器、angular、觀察者select值已經發生了變化 htmlSelect.dispatchEvent(new Event('change')); }); ``` ## 上結 本結我們使用`getTestScheduler()`方法控制了`MockApi`返回值的時機。這使得我們在脫離后臺的開發中,即可以決定http請求返回什么值,又可以決定其值在什么時候返回。這有利于我們掌握組件在http請求前后的狀態。 我們還調用了`formControl`的`setValue()`方法來快速的模擬用戶的點擊,這為以后使用代碼來完全代替不可靠的人工點擊打下了基礎。 | 名稱 | 鏈接 | | -------- | ------------------------------------------------------------ | | 本節源碼 | [https://github.com/mengyunzhi/angular11-guild/archive/step6.2.3.zip](https://github.com/mengyunzhi/angular11-guild/archive/step6.2.3.zip) |
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看