<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
        博客園  :: 首頁  :: 聯系 :: 管理

      前端angular基礎測試篇

      Posted on 2021-10-24 22:30  雪庭  閱讀(688)  評論(0)    收藏  舉報

       

      jest提供覆蓋率報告等開發者所需要的所有測試工具,jest是一款幾乎零配置的 測試框架。angular jest單元測試的寫法為三步,引入測試內容,運行測試內容, 最后進行比較,是否達到預期。jest中的斷言使用expect, 它接受一個參數,就 是運行測試內容的結果,返回一個對象,這個對象來調用匹配器 (toBe) ,匹配器的參數就是我們的預期結果,這樣就可以對結果和預 期進行對比了,也就可以判斷對不對了。

      兩個必會的方法test方法:Jest封裝的測試方法,一般填寫兩個參數,描述和測 試方法,expect方法 :預期方法,就是你調用了什么方法,傳遞了什么參數,得 到的預期是什么。

      1 常用jest斷言

      • toBe:絕對相等(=)
      // 在src/functions.js中創建被測試的模塊
      export default {
        sum(a, b) {
          return a + b;
        }
      }
      
      // 在test/functions.test.js文件中創建測試用例
      import functions  from '../src/functions';
      
      test('sum(2 + 2) 等于 4', () => {
        expect(functions.sum(2, 2)).toBe(4);
      })
      
      • not:允許你測試結果不等于某個值的情況
      // 在src/functions.js中創建被測試的模塊
      export default {
        sum(a, b) {
          return a + b;
        }
      }
      
      // functions.test.js
      import functions  from '../src/functions'
      
      test('sum(2, 2) 不等于 5', () => {
        expect(functions.sum(2, 2)).not.toBe(5);
      })
      
      • toEqual:簡單類型絕對匹配;復雜類型內容結果的匹配
      // functions.js
      export default {
        getAuthor() {
          return {
            name: 'LITANGHUI',
            age: 24,
          }
        }
      }
      // functions.test.js
      import functions  from '../src/functions';
      
      test('getAuthor()返回的對象深度相等', () => {
        expect(functions.getAuthor()).toEqual(functions.getAuthor());
      })
      
      test('getAuthor()返回的對象內存地址不同', () => {
        expect(functions.getAuthor()).not.toBe(functions.getAuthor());
      })
      
      • toHaveLength:方便的用來測試字符串和數組類型的長度是否滿足預期
      // functions.js
      export default {
        getIntArray(num) {
          if (!Number.isInteger(num)) {
            throw Error('"getIntArray"只接受整數類型的參數');
          }
      
          let result = [];
          for (let i = 0, len = num; i < len; i++) {
            result.push(i);
          }
          
          return result;
        }
      }
      // functions.test.js
      import functions  from '../src/functions';
      
      test('getIntArray(3)返回的數組長度應該為3', () => {
        expect(functions.getIntArray(3)).toHaveLength(3);
      })
      
      • toThorw:可能夠讓我們測試被測試方法是否按照預期拋出異常,但是在使用時 需要注意的是:我們必須使用一個函數將將被測試的函數做一個包裝,正如上 面getIntArrayWrapFn所做的那樣,否則會因為函數拋出導致該斷言失敗
      // functions.test.js
      import functions  from '../src/functions';
      
      test('getIntArray(3.3)應該拋出錯誤', () => {
        function getIntArrayWrapFn() {
          functions.getIntArray(3.3);
        }
        expect(getIntArrayWrapFn).toThrow('"getIntArray"只接受整數類型的參數');
      mockImplementation})
      
      • toBeNull():匹配null
      • toBeUndefined():匹配undefined
      • toBeDefined():匹配非undefined
      • toBeTruthy():匹配轉化后為true
      • toBeFalsy():匹配轉化后為false
      • toBeGreaterThan():相當于大于號
      • toBeLessThan():相當于小于號
      • toBeGreaterThanOrEqual():相當于大于等于號
      • toBeLessThanOrEqual():相當于小于等于號
      • toBeCloseTo():解決js浮點錯誤
      • toMatch(regExp/string):用正則表達式或者字符串匹配字符串片段
      • toContain():匹配數組或者Set中的某一項

      2 mock函數

      進行單元測試時,要測試的內容依賴其他內容,比如異步請求,會依賴網絡,很 可能造成測試達不到效果。能不能把依賴變成可控的內容?這就用到mack。mack 就是把依賴替換成我們可控的內容,實現測試的內容和它的依賴項隔離。那怎么 才能實現mock呢?使用mack 函數。在jest中,當我們談論mack的時候,其實談 論的就是使用mack函數代替依賴。mack函數就是一個虛擬的或假的函數,所以對 它來說,最重要的就是實現依賴的全部功能,從而起到替換的作用。通常,mock 函數會提供以下三個功能,來實現替換:函數的調用捕獲,設置函數返回值,改 變原函數的實現。在jest 創建一個mock 函數最簡單的方法就是調用jest.fn() 方法。

      2.1 函數的調用捕捉

      捕獲調用指的是這個函數有沒有被調用,調用的參數是什么,返回值是什么,通 常用于測試回調函數,模擬真實的回調函數。

      // functions.js
      export default {
        forEachFun: (array: any[], callback: Function) => {
          array.forEach((i) => callback(i));
        }
      }
      // functions.test.js
      import functions  from '../src/functions';
      test('forEachFun調用每個方法', () => {
        const mockFun = jest.fn();
        const testArr = [1, 2];
        functions.forEachFun(testArr, mockFun);
        console.log(mockFun.mock);
        // expect(mockFun.mock.calls.length).toBe(2);
        expect(mockFun).toHaveBeenCalled();
        expect(mockFun).toBeCalledTimes(2);
        expect(mockFun).toBeCalledWith(1);
        expect(mockFun).toBeCalledWith(2);
      });
      // mock函數mockFun屬性是一個對象,打印結果:
      {
        calls: [ [ 1 ], [ 2 ] ],
        instances: [ undefined, undefined ],
        invocationCallOrder: [ 1, 2 ],
        results:[ 
              { type: 'return', value: undefined },
              { type: 'return', value: undefined }
        ] 
      }
      

      calls 保存的就是調用狀態。calls 是一個數組,每一次的調用都組成數組的 一個元素,在這里調用了兩次,就有兩個元素。每一個元素又是一個數組,它 則表示的是函數調用時的參數,因為每次的調用都傳遞了一個參數給函數,所 以數組只有一項。如果有多個參數,數組就有多項,按照函數中的參數列表依 次排列。這時候,就可以做斷言,函數調用了幾次,就判斷 calls.length. expect(mockFun.mock.calls.length).toBe(2) 就是斷言函數 是不是調用了兩次。expcet(mockFun.mock.calls[0][0]) .toBe(1)就是斷言第 一次調用的時候傳遞的參數是不是1. 可能覺得麻煩了, 的確有點麻煩了,幸 好,jest 對函數的mock參數進行了簡單的封裝,提供了簡單的匹配器。

      // 用來判斷mock函數是否被掉用過
      toHaveBeenCalled()/toBeCalled()
      // 用來判斷mock函數調用過幾次
      toHaveBeenCalledTimes(number)/toBeCalledTimes(number)
      // 用來判斷是否使用了特定參數調mock函數
      toHaveBeenCalledWith(arg1,arg2,...)/toBeCalledWith(arg1,arg2,...)
      

      有的時候,由于后端沒有開發好,或網絡問題,不想調用函數,直接獲取到函數 的返回值就可以了,比如異步函數, 直接返回一個Observable就好了,根本沒有 必要請求服務器。

      test('設置函數返回值', () => {
        // 普通返回
        const mockFun = jest.fn();
        mockFun.
        const result: string = mockFun();
        expect(mockFun).toBeCalledTimes(1);
        expect(result).toEqual({name: 'shao'});
        // observable返回
        const observableFun = jest.fn();
        observableFun.mockReturnValue(of({name: 'shao'}));
        const observableResult: Observable<any> = observableFun();
        observableResult.subscribe((res) => {
          expect(res).toEqual({name: 'shao'});
        });
      });
      

      2.2 使用spyOn間諜測試服務

      服務往往是最容易進行單元測試的文件。下面是一些針對 ValueService 的同步 和異步單元測試,甚至不需要 Angular 測試工具的幫助。

      // Straight Jasmine testing without Angular's testing support
      describe('ValueService', () => {
        let service: ValueService;
        beforeEach(() => { service = new ValueService(); });
      
        it('#getValue should return real value', () => {
          expect(service.getValue()).toBe('real value');
        });
      
        it('#getObservableValue should return value from observable',
          () => {
          service.getObservableValue().subscribe(value => {
            expect(value).toBe('observable value');
          });
        });
      });
      

      服務通常依賴于angular 在構造函數中注入的其它服務。在很多情況下,調用 服務的構造函數時,很容易手動創建和注入這些依賴。

      // ValueService.ts
      @Injectable({
        providedIn: 'root'
      })
      export class ValueService {
        value = 'real value';
      
        getValue(): string { return this.value; }
        setValue(value: string): void { this.value = value; }
      
        getObservableValue(): Observable<string> { return of('observable value'); }
      
        getPromiseValue(): Promise<string> { return Promise.resolve('promise value'); }
      
        getObservableDelayValue(): Observable<string> {
          return of('observable delay value').pipe(delay(10));
        }
      }
      
      // ValueService.spec.ts
      export class FakeValueService extends ValueService {
        value = 'faked service value';
      }
      
      describe('MasterService without angular testing support', () => {
        let masterService: MasterService;
      
        it('#getValue 返回 service', () => {
          masterService = new MasterService(new ValueService());
          expect(masterService.getValue()).toBe('real value');
        });
      
        it('#getValue 使用 fakeServiece', () => {
          masterService = new MasterService(new FakeValueService());
          expect(masterService.getValue()).toBe('faked service value');
        });
      
        it('#getValue 使用 fake object', () => {
          const fake = { getValue: () => 'fake value' };
          masterService = new MasterService(fake as ValueService);
          expect(masterService.getValue()).toBe('fake value');
        });
      
        it('#getValue 返回 by a spy', () => {
          const valueService: ValueService = new ValueService();
          jest.spyOn(valueService, 'getValue').mockReturnValueOnce('test');
          masterService = new MasterService(valueService);
          expect(masterService.getValue()).toBe('test');
        });
      });
      

      第一個測試使用 new 創建了一個 ValueService,并把它傳給了 MasterService 的構造函數。然而,注入真實服務很難工作良好,因為大多數被依賴的服務都很 難創建和控制。還可以模擬依賴、使用仿制品,或者在相關的服務方法上創建一 個測試間諜spyOn。

      2.3 angular TestBed

      TestBed 是 Angular 測試實用工具中最重要的。 TestBed 創建了一個動態構造 的 Angular 測試模塊,用來模擬一個 Angular 的 @NgModule 。 TestBed.configureTestingModule() 方法接受一個元數據對象,它可以擁有 @NgModule的大部分屬性。要測試某個服務,你可以在元數據屬性 providers 中 設置一個要測試或模擬的服務數組。

      let masterService: MasterService;
      let valueService: ValueService;
      
      beforeEach(() => {
        TestBed.configureTestingModule({
          providers: [
            MasterService, ValueService
          ]
        });
        masterService = TestBed.inject(MasterService);
        valueService = TestBed.inject(ValueService);
      });
      

      測試帶依賴的服務時,同時使用spyOn:

      // value.service.ts
      @Injectable()
      export class MasterService {
        constructor(private valueService: ValueService) { }
        getValue(): string {
          return this.valueService.getValue();
        }
      }
      // value.service.spec.ts
      describe('MasterService動態構建', () => {
        let masterService: MasterService;
        let valueService: ValueService;
      
        beforeEach(() => {
          TestBed.configureTestingModule({
            providers: [
              MasterService, ValueService
            ]
          });
          masterService = TestBed.inject(MasterService);
          valueService = TestBed.inject(ValueService);
        });
      
        it('#getValue從spy返回', () => {
          const stubValue = 'stub value';
          jest.spyOn(valueService, 'getValue').mockReturnValue(stubValue);
          expect(masterService.getValue()).toBe(stubValue);
          expect(valueService.getValue).toBeCalledTimes(1);
          window.console.log(valueService.getValue);
          expect(valueService.getValue()).toBe(stubValue);
        });
      });
      

      Author: flysic

      Created: 2021-10-24 Sun 22:26

      Validate

      主站蜘蛛池模板: 国产乱妇无乱码大黄aa片| 亚洲国产片一区二区三区| 国产偷人爽久久久久久老妇app| 在线成人| 国内极度色诱视频网站| 国产精品99久久久久久董美香 | 欧美精欧美乱码一二三四区 | 一卡2卡三卡4卡免费网站| 亚欧洲乱码视频一二三区| 亚洲天堂av日韩精品| 国产成人啪精品午夜网站| 久久se精品一区二区三区| 美日韩精品综合一区二区| 日本精品网| 国产一区二区一卡二卡| 亚洲午夜激情久久加勒比| 亚洲欧美中文字幕5发布| 小嫩批日出水无码视频免费| 国产一区二区在线激情往| 日韩中文字幕v亚洲中文字幕| 久久人妻精品国产| 色悠悠成人综合在线视频| www亚洲精品| 看免费的无码区特aa毛片 | 日本一区不卡高清更新二区 | 亚洲AV色香蕉一区二区蜜桃小说| 亚洲av成人一区在线| 国产精品自拍中文字幕| 亚洲国产精品自产在线播放| 熟女一区二区中文字幕| 国产精品毛片在线看不卡| 四虎国产精品成人免费久久 | 日本精品成人一区二区三区视频| 蜜芽久久人人超碰爱香蕉| 欧美乱妇高清无乱码免费| 国产精品久久久久鬼色| 蜜桃网址| 日本亚洲欧洲无免费码在线| 91精品国产蜜臀在线观看| 亚洲欧美在线观看品| 国产高清国产精品国产专区|