亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 語言 > JavaScript > 正文

angularjs中的單元測試實例

2024-05-06 16:11:31
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了angularjs中的單元測試實例,本文主要說說利用karma和jasmine來進行ng模塊的單元測試,需要的朋友可以參考下
 
 

當ng項目越來越大的時候,單元測試就要提上日程了,有的時候團隊是以測試先行,有的是先實現功能,后面再測試功能模塊,這個各有利弊,今天主要說說利用karma和jasmine來進行ng模塊的單元測試.

什么是Karma

karma是一個單元測試的運行控制框架,提供以不同環境來運行單元測試,比如chrome,firfox,phantomjs等,測試框架支持jasmine,mocha,qunit,是一個以nodejs為環境的npm模塊.

安裝測試相關的npm模塊建議使用----save-dev參數,因為這是開發相關的,一般的運行karma的話只需要下面兩個npm命令

復制代碼代碼如下:

npm install karma --save-dev
npm install karma-junit-reporter --save-dev

 

安裝karma的時候會自動的安裝一些常用的模塊,參考karma代碼里的package.json文件的peerDependencies屬性

 

復制代碼代碼如下:

 "peerDependencies": {
        "karma-jasmine": "~0.1.0",
        "karma-requirejs": "~0.2.0",
        "karma-coffee-preprocessor": "~0.1.0",
        "karma-html2js-preprocessor": "~0.1.0",
        "karma-chrome-launcher": "~0.1.0",
        "karma-firefox-launcher": "~0.1.0",
        "karma-phantomjs-launcher": "~0.1.0",
        "karma-script-launcher": "~0.1.0"
  }

 

然后一個典型的運行框架通常都需要一個配置文件,在karma里可以是一個karma.conf.js,里面的代碼是一個nodejs風格的,一個普通的例子如下:

復制代碼代碼如下:

module.exports = function(config){
  config.set({
    // 下面files里的基礎目錄
    basePath : '../',
    // 測試環境需要加載的JS信息
    files : [
      'app/bower_components/angular/angular.js',
      'app/bower_components/angular-route/angular-route.js',
      'app/bower_components/angular-mocks/angular-mocks.js',
      'app/js/**/*.js',
      'test/unit/**/*.js'
    ],
    // 是否自動監聽上面文件的改變自動運行測試
    autoWatch : true,
    // 應用的測試框架
    frameworks: ['jasmine'],
    // 用什么環境測試代碼,這里是chrome`
    browsers : ['Chrome'],
    // 用到的插件,比如chrome瀏覽器與jasmine插件
    plugins : [
            'karma-chrome-launcher',
            'karma-firefox-launcher',
            'karma-jasmine',
            'karma-junit-reporter'
            ],
    // 測試內容的輸出以及導出用的模塊名
    reporters: ['progress', 'junit'],
    // 設置輸出測試內容文件的信息
    junitReporter : {
      outputFile: 'test_out/unit.xml',
      suite: 'unit'
    }

 

  });
};

 

這里要注意的時,上面的插件大部分都不需要單獨安裝,因為安裝karma的時候已經安裝了,這里只有karma-junit-reporter導出插件需要單獨安裝,想要了解更多的關于配置文件的信息可以,點擊這里

karma就講到這里,想了解更多關于它的信息可以,點擊這里

什么是jasmine

Jasmine is a behavior-driven development framework for testing JavaScript code. It does not depend on any other JavaScript frameworks. It does not require a DOM. And it has a clean, obvious syntax so that you can easily write tests.

上面是jasmine官方文檔里對它的解釋,下面用中文簡單的翻譯下

jasmine是一個行為驅動開發的測試框架,不依賴任何js框架以及dom,是一個非常干凈以及友好API的測試庫.

下面簡單的以一個例子來說明它的用法

定義一個測試文件命令為test.js

復制代碼代碼如下:

describe("A spec (with setup and tear-down)", function() {
  var foo;

 

  beforeEach(function() {
    foo = 0;
    foo += 1;
  });

  afterEach(function() {
    foo = 0;
  });

  it("is just a function, so it can contain any code", function() {
    expect(foo).toEqual(1);
  });

  it("can have more than one expectation", function() {
    expect(foo).toEqual(1);
    expect(true).toEqual(true);
  });
});

 

上面的例子來自于官網,這里只說下幾個重要的API,更多的用法請,點擊這里

1.首先任何一個測試用例以describe函數來定義,它有兩參數,第一個用來描述測試大體的中心內容,第二個參數是一個函數,里面寫一些真實的測試代碼

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

3.expect主要用來計算一個變量或者一個表達式的值,然后用來跟期望的值比較或者做一些其它的事件

4.beforeEach與afterEach主要是用來在執行測試任務之前和之后做一些事情,上面的例子就是在執行之前改變變量的值,然后在執行完成之后重置變量的值

最后要說的是,describe函數里的作用域跟普通JS一樣都是可以在里面的子函數里訪問的,就像上面的it訪問foo變量

想要運行上面的測試例子可以通過karar來運行,命令例子如下:

 

復制代碼代碼如下:

karma start test/karma.conf.js

 

下面我們重點的說說ng里的控制器,指令,服務模塊的單元測試.

NG的單元測試

因為ng本身框架的原因,模塊都是通過di來加載以及實例化的,所以為了方便配合jasmine來編寫測試腳本,所以官方提供了angular-mock.js的一個測試工具類來提供模塊定義,加載,注入等.

下面說說ng-mock里的一些常用方法

1.angular.mock.module 此方法同樣在window命名空間下,非常方便調用

module是用來配置inject方法注入的模塊信息,參數可以是字符串,函數,對象,可以像下面這樣使用

復制代碼代碼如下:

beforeEach(module('myApp.filters'));

 

beforeEach(module(function($provide) {
      $provide.value('version', 'TEST_VER');
}));

 

它一般用在beforeEach方法里,因為這個可以確保在執行測試任務的時候,inject方法可以獲取到模塊配置

1.angular.mock.inject 此方法同樣在window命名空間下,非常方便調用

inject是用來注入上面配置好的ng模塊,方面在it的測試函數里調用,常見的調用例子如下:

 

復制代碼代碼如下:

angular.module('myApplicationModule', [])
      .value('mode', 'app')
      .value('version', 'v1.0.1');

 


  describe('MyApp', function() {

    // You need to load modules that you want to test,
    // it loads only the "ng" module by default.
    beforeEach(module('myApplicationModule'));


    // inject() is used to inject arguments of all given functions
    it('should provide a version', inject(function(mode, version) {
      expect(version).toEqual('v1.0.1');
      expect(mode).toEqual('app');
    }));


    // The inject and module method can also be used inside of the it or beforeEach
    it('should override a version and test the new version is injected', function() {
      // module() takes functions or strings (module aliases)
      module(function($provide) {
        $provide.value('version', 'overridden'); // override version here
      });

      inject(function(version) {
        expect(version).toEqual('overridden');
      });
    });
  });

 

上面是官方提供的一些inject例子,代碼很好看懂,其實inject里面就是利用angular.inject方法創建的一個內置的依賴注入實例,然后里面的模塊注入跟普通ng模塊里的依賴處理是一樣的

簡單的介紹完ng-mock之后,下面我們分別以控制器,指令,過濾器來編寫一個簡單的單元測試.

ng里控制器的單元測試

定義一個簡單的控制器

復制代碼代碼如下:

var myApp = angular.module('myApp',[]);

 

    myApp.controller('MyController', function($scope) {
      $scope.spices = [{"name":"pasilla", "spiciness":"mild"},
                       {"name":"jalapeno", "spiciness":"hot hot hot!"},
                       {"name":"habanero", "spiciness":"LAVA HOT!!"}];
      $scope.spice = "hello feenan!";
});

 

然后我們編寫一個測試腳本

復制代碼代碼如下:

describe('myController function', function() {

 

  describe('myController', function() {
    var $scope;

    beforeEach(module('myApp'));

    beforeEach(inject(function($rootScope, $controller) {
      $scope = $rootScope.$new();
      $controller('MyController', {$scope: $scope});
    }));

    it('should create "spices" model with 3 spices', function() {
      expect($scope.spices.length).toBe(3);
    });

    it('should set the default value of spice', function() {
      expect($scope.spice).toBe('hello feenan!');
    });
  });

});

 

上面利用了$rootScope來創建子作用域,然后把這個參數傳進控制器的構建方法$controller里去,最終會執行上面的控制器里的方法,然后我們檢查子作用域里的數組數量以及字符串變量是否跟期望的值相等.

想要了解更多關于ng里的控制器的信息,可以點擊這里

ng里指令的單元測試

定義一個簡單的指令

 

復制代碼代碼如下:

var app = angular.module('myApp', []);

 

app.directive('aGreatEye', function () {
    return {
        restrict: 'E',
        replace: true,
        template: '<h1>lidless, wreathed in flame, 1 times</h1>'
    };
});

 

然后我們編寫一個簡單的測試腳本

 

復制代碼代碼如下:

describe('Unit testing great quotes', function() {
    var $compile;
    var $rootScope;

 

    // Load the myApp module, which contains the directive
    beforeEach(module('myApp'));

    // Store references to $rootScope and $compile
    // so they are available to all tests in this describe block
    beforeEach(inject(function(_$compile_, _$rootScope_){
      // The injector unwraps the underscores (_) from around the parameter names when matching
      $compile = _$compile_;
      $rootScope = _$rootScope_;
    }));

    it('Replaces the element with the appropriate content', function() {
        // Compile a piece of HTML containing the directive
        var element = $compile("<a-great-eye></a-great-eye>")($rootScope);
        // fire all the watches, so the scope expression 1 will be evaluated
        $rootScope.$digest();
        // Check that the compiled element contains the templated content
        expect(element.html()).toContain("lidless, wreathed in flame, 2 times");
    });
});

 

上面的例子來自于官方提供的,最終上面的指令將會這用在html里使用

 

復制代碼代碼如下:

<a-great-eye></a-great-eye>

 

測試腳本里首先注入$compile與$rootScope兩個服務,一個用來編譯html,一個用來創建作用域用,注意這里的_,默認ng里注入的服務前后加上_時,最后會被ng處理掉的,這兩個服務保存在內部的兩個變量里,方便下面的測試用例能調用到

$compile方法傳入原指令html,然后在返回的函數里傳入$rootScope,這樣就完成了作用域與視圖的綁定,最后調用$rootScope.$digest來觸發所有監聽,保證視圖里的模型內容得到更新

然后獲取當前指令對應元素的html內容與期望值進行對比.

想要了解更多關于ng里的指令的信息,可以點擊這里

ng里的過濾器單元測試

定義一個簡單的過濾器

復制代碼代碼如下:

var app = angular.module('myApp', []);
app.filter('interpolate', ['version', function(version) {
    return function(text) {
      return String(text).replace(//%VERSION/%/mg, version);
    };
  }]);

然后編寫一個簡單的測試腳本
復制代碼代碼如下:

describe('filter', function() {
  beforeEach(module('myApp'));

 


  describe('interpolate', function() {

    beforeEach(module(function($provide) {
      $provide.value('version', 'TEST_VER');
    }));


    it('should replace VERSION', inject(function(interpolateFilter) {
      expect(interpolateFilter('before %VERSION% after')).toEqual('before TEST_VER after');
    }));
  });
});

 

上面的代碼先配置過濾器模塊,然后定義一個version值,因為interpolate依賴這個服務,最后用inject注入interpolate過濾器,注意這里的過濾器后面得加上Filter后綴,最后傳入文本內容到過濾器函數里執行,與期望值進行對比.

總結

利用測試來開發NG有很多好處,可以保證模塊的穩定性,還有一點就是能夠深入的了解ng的內部運行機制,所以建議用ng開發的同學趕緊把測試補上吧!


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产成人精品免高潮费视频| 深夜福利日韩在线看| 欧美午夜www高清视频| 91精品国产精品| 精品国产乱码久久久久久虫虫漫画| 欧美中文字幕在线| 亚洲在线免费看| 日韩一区二区在线视频| 国产精品久久77777| 久久久女人电视剧免费播放下载| 欧美激情第1页| 国产精品伦子伦免费视频| 欧美午夜丰满在线18影院| 97精品在线观看| 日韩精品免费视频| 久久69精品久久久久久国产越南| 国产亚洲精品久久久优势| 久久精品中文字幕免费mv| 亚洲精品美女在线| 91最新在线免费观看| 亚洲欧美日韩视频一区| 久久久久久久97| www.久久久久| 亚洲丝袜在线视频| 在线视频欧美性高潮| 国产成人av在线播放| 亚洲女人天堂网| 欧美高跟鞋交xxxxhd| 国产精品99久久久久久白浆小说| 国产精品综合网站| 久久噜噜噜精品国产亚洲综合| 欧美夫妻性生活xx| 亚洲男人的天堂在线| 欧美日韩国产综合视频在线观看中文| 精品成人69xx.xyz| 热久久视久久精品18亚洲精品| 亚洲成年人在线播放| 亚洲2020天天堂在线观看| 视频直播国产精品| 欧美一级成年大片在线观看| 欧美日韩成人免费| 欧美孕妇与黑人孕交| 91在线直播亚洲| 中文字幕免费精品一区| 97超级碰碰人国产在线观看| 精品偷拍各种wc美女嘘嘘| 精品二区三区线观看| 在线成人一区二区| 日韩欧美精品网站| 亚洲天堂av电影| 亚洲精品乱码久久久久久按摩观| 成人欧美一区二区三区在线湿哒哒| 国产v综合ⅴ日韩v欧美大片| 中文字幕国产精品| 亚洲人成网7777777国产| 日韩美女中文字幕| 久久亚洲国产精品成人av秋霞| 日韩中文av在线| 久久影视电视剧凤归四时歌| 成人欧美一区二区三区在线湿哒哒| 国产一区二区黑人欧美xxxx| 91免费综合在线| 中文字幕综合在线| 国产男女猛烈无遮挡91| 亚洲人精选亚洲人成在线| 欧美日韩国产成人| 久久亚洲精品小早川怜子66| 欧美极品在线视频| 91在线无精精品一区二区| 国产欧美va欧美va香蕉在线| 1769国内精品视频在线播放| 成人性教育视频在线观看| 精品一区二区三区电影| 亚洲天堂av在线播放| 97超级碰碰人国产在线观看| 久久久久久久久亚洲| 日本中文字幕成人| 中文字幕av一区中文字幕天堂| 久久精品中文字幕电影| 姬川优奈aav一区二区| 91丨九色丨国产在线| 色综合久久88色综合天天看泰| 国产精品成人va在线观看| 久久久久国产精品免费网站| 成人黄色中文字幕| 欧美日韩一区二区免费视频| 久久69精品久久久久久国产越南| 久久久精品视频在线观看| 成人国产精品一区| 久久久久久国产精品| 欧美日韩国产成人| 国产一区香蕉久久| 日韩中文字幕在线精品| 91久久精品美女高潮| 最近2019免费中文字幕视频三| 欧美在线亚洲在线| 狠狠躁夜夜躁人人爽超碰91| 92国产精品久久久久首页| 亚洲成色999久久网站| 午夜精品福利视频| 最新亚洲国产精品| 国产免费一区二区三区在线能观看| 国产偷国产偷亚洲清高网站| 色av吧综合网| 欧美精品中文字幕一区| 亚洲r级在线观看| 欧美成人精品xxx| 日韩精品欧美激情| 日韩精品中文字幕在线观看| 欧美与欧洲交xxxx免费观看| 欧美色道久久88综合亚洲精品| 成年人精品视频| 日本欧美在线视频| 日韩网站在线观看| 国产精品99久久久久久白浆小说| 国产精品第一区| 欧美性jizz18性欧美| 一区二区三区高清国产| 久久久中文字幕| 精品欧美一区二区三区| 中日韩美女免费视频网站在线观看| 欧美日韩亚洲国产一区| 亚洲精品国产精品乱码不99按摩| 中文欧美日本在线资源| 国产一区在线播放| 国产精品黄视频| 久久精品久久久久久| 性色av一区二区咪爱| 色阁综合伊人av| 国产福利精品视频| 91免费看片网站| 国产精品十八以下禁看| 国产午夜精品一区理论片飘花| www国产亚洲精品久久网站| 欧美福利视频网站| 久久久久久久av| 福利一区视频在线观看| 亚洲欧美成人一区二区在线电影| 91午夜理伦私人影院| 国产成人精品在线播放| 欧美成人精品xxx| 久久视频在线播放| 亚洲成人精品av| www.欧美精品一二三区| 亚洲欧美国产精品久久久久久久| 亚洲精品白浆高清久久久久久| 日韩av在线免费观看一区| 国产欧美日韩丝袜精品一区| 欧美日韩成人免费| 上原亚衣av一区二区三区| 久久久久久久成人| 亚洲精品一区中文| 成人有码在线播放| 欧美黑人狂野猛交老妇| 国产一区二区三区在线免费观看| 国产精品电影一区| 欧美激情2020午夜免费观看| 亚洲欧美激情在线视频| 国产精品嫩草影院久久久| 欧美大片欧美激情性色a∨久久| 亚洲精品国产美女| 欧美在线观看网址综合| 国产精品美女久久久久av超清| 欧美成人精品在线播放|