AngularJS 單元測試 Karma jasmine

  當AngularJS項目愈來愈大時候,須要進行單元測試,能夠先開發功能再進行測試,也能夠先進行測試。後端

1、karma 瀏覽器

  是一個基於Node.js(先要安裝)的JavaScript測試執行過程管理工具(Test Runner)。Test Runner是用來跑測試的工具,即,寫好測試,讓它跑起來。服務器

  可用於測試全部主流Web瀏覽器,也可集成到CI(Continuous integration)工具,也可和其餘代碼編輯器一塊兒使用。網絡

  一個強大特性就是,能夠監控(Watch)文件的變化,而後自行執行,經過console.log顯示測試結果。app

2、jasmine框架

  是一個用於JS代碼測試的行爲驅動開發的框架,它不依賴於任何其餘的JS框架以及DOM,是一個簡潔及友好的API測試庫。異步

  是代碼中用來寫斷言的庫,測試代碼中expect和toBe等函數都來自它。編輯器

3、mock庫函數

  angular-mocks.js 是一個AngularJS提供的一個用來Mock內置服務的獨立測試庫。如對$httpBackend,$exceptionHandler。工具

  $httpBackend 經過本地調用來模擬服務器對象。模擬http後端,即服務器。

  $httpBackend.whenGet("/someUrl").respond({name:'wolf'},{'X-Record-Count':100'});

  即,聲明瞭一個模擬服務端,當測試代碼請求Get/someUrl地址時候,被$httpBackend攔截,並返回一個JSON對象{name:'wolf'},同時,返回一個額外的response header : X-Record-Count 值爲100.

  另外,須要$httpBackend.flush函數觸發調用。並且,不要在mock寫複雜業務邏輯,給出固定數據,返回固定數據。

4、jasmine語法

一、一個測試用例以describe函數來定義,它有兩參數,第一個用來描述測試內容,第二個參數是一個函數,寫一些真實的測試代碼。

二、it是用來定義單個具體測試任務,也有兩個參數,第一個用來描述測試內容,第二個參數是一個函數,裏面存放一些測試方法。

三、expect主要用來計算一個變量或者一個表達式的值、而後用來跟指望的值比較或者作一些其它的事件。

四、beforeEach與afterEach主要是用來在執行測試任務以前和以後作一些事情,上面的例子就是在執行以前改變變量的值,而後在執行完成以後重置變量的值。

另外,describe函數裏的做用域跟普通JS同樣都是能夠在裏面的子函數裏訪問的,就像上面的it訪問foo變量。

5、例子

一、測試一個服務

  一個服務:

angular.module("app.services").service("constService", function(){
  this.myConstanat = 2;
});

  編寫測試(jasmine)

describe("constService", function () {
    var out;                                     // 被測對象
    beforeEach(function () {
        module('app.services');                 // 導入模塊
     inject(function (constService) {        // 注入依賴
          out = constService;                   // 關聯被測對象實例
    }));

    it("one == 1", function () {
        expect(out.myConstant).toEqual(1);
    });
});        

二、模擬http請求返回值

  通常咱們寫$http請求,用以下代碼到服務器端請求,函數經過http get請求獲得user的值。

//經過http請求獲得user
$scope.GetUser = function(){
    $http.get('/auth.py').then(function(response) {
    $scope.user = response.data;
});

  單元測試裏咱們並不真的但願發送一個http get請求來運行測試,由於那樣會使測試複雜化,網絡相關的各類問題都會致使測試失敗,並且angular http服務是異步的,而咱們但願測試是同步的。

 var scope,ctrl;
     //inject利用angular的依賴注入,將須要的模塊,服務插入做用域
     beforeEach(inject(function ($controller, $rootScope) {
        //模擬生成scope, $rootScope是angular中的頂級scope,angular中每一個controller中的     
        //scope都是rootScope new出來的
        scope = $rootScope.$new();
        //模擬生成controller 並把先前生成的scope傳入以方便測試
        ctrl = $controller('unitTestCtrl', {$scope: scope});
     }));
    //開始測試
    //模擬http get的返回值, 插入injector服務,讓咱們可以在測試代碼中使用依賴注入來得到須要的服務
    it('GetUser should fetch users', inject(function($injector){
        // $httpBackend 是由angular mock提供的一個模擬http請求返回服務
        // 能夠用它來模擬http請求的返回值
        // 這裏經過$injector來獲取它的實例        
        var $httpBackend = $injector.get('$httpBackend');
        
        // $httpBackend 在Get方法,對 '/auth.py' 的url將會返回 一個jason對象
        // {customerId: '1',name:'benwei'} 
        $httpBackend.when('GET', '/auth.py').respond({customerId: '1',name:'benwei'});
        
        //以上爲測試前的準備工做, 也能夠把這部分代碼放在beforeEach裏,
        //但要注意: beforeEach裏的設置將影響全部在它做用域的測試用例。
        
        
        //運行GetUser函數        
        scope.GetUser();
        
        //把http的異步轉爲同步,要求$httpBackend馬上返回數據 
        $httpBackend.flush();
        
        // 查看scope.user的值是否正確
        expect(scope.user).toEqual({customerId: '1',name:'benwei'});
    }));
相關文章
相關標籤/搜索