最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

在JavaScript的AngularJS庫中進行單元測試的方法

 更新時間:2015年06月23日 09:48:36   投稿:goldensun  
這篇文章主要介紹了在JavaScript的AngularJS庫中進行單元測試的方法,主要針對AngularJS中的控制器相關(guān),需要的朋友可以參考下

開發(fā)者們都一致認為單元測試在開發(fā)項目中十分有好處。它們幫助你保證代碼的質(zhì)量,從而確保更穩(wěn)定的研發(fā),即使需要重構(gòu)時也更有信心。

201562393334308.png (257×221)

 測試驅(qū)動開發(fā)流程圖

AngularJS的代碼聲稱其較高的可測性確實是合理的。單單文檔中列出端對端的測試實例就能說明。就像AngularJS這樣的項目雖然都說單元測試很簡單但真正做好卻不容易。即使官方文檔中以提供了詳盡的實例,但在我的實際應(yīng)用中卻還是很有挑戰(zhàn)。這里我就簡單示范一下我是怎么操作的吧.

Instant Karma

Karma 是來Angular團隊針對JavaScript開發(fā)的一個測試運行框架。它很方便的實現(xiàn)了自動執(zhí)行測試任務(wù)從而替代了繁瑣的手工操作(好比回歸測試集或是加載目標測試的依賴關(guān)系)Karma 和Angular的協(xié)作就好比花生醬和果凍.

只需要在Karma中定義好配置文件啟動它,接下來它就會在預(yù)期的測試環(huán)境下的自動執(zhí)行測試用例。你可以在配置文件中制定相關(guān)的測試環(huán)境。angular-seed,是我強烈推薦的可以快速實施的方案。在我近期的項目中Karma 的配置如下:
 

module.exports = function(config) {
  config.set({
    basePath: '../',
 
    files: [
      'app/lib/angular/angular.js',
      'app/lib/angular/angular-*.js',
      'app/js/**/*.js',
      'test/lib/recaptcha/recaptcha_ajax.js',
      'test/lib/angular/angular-mocks.js',
      'test/unit/**/*.js'
    ],
 
    exclude: [
      'app/lib/angular/angular-loader.js',
      'app/lib/angular/*.min.js',
      'app/lib/angular/angular-scenario.js'
    ],
 
    autoWatch: true,
 
    frameworks: ['jasmine'],
 
    browsers: ['PhantomJS'],
 
    plugins: [
      'karma-junit-reporter',
      'karma-chrome-launcher',
      'karma-firefox-launcher',
      'karma-jasmine',
      'karma-phantomjs-launcher'
    ],
 
    junitReporter: {
      outputFile: 'test_out/unit.xml',
      suite: 'unit'
    }
 
  })
}


這個跟angular-seed的默認配置類似只不過有以下幾點不同:

  •     需要更改瀏覽器從Chrome 轉(zhuǎn)到PhantomJS, 這樣每次跳轉(zhuǎn)時無需再打開新的瀏覽器窗口,但在OSX系統(tǒng)會有窗口延遲。所以這個插件還有瀏覽器設(shè)置都做了更改。
  •     由于我的應(yīng)用需要引用Google的Recaptcha服務(wù)因此添加了依賴的recaptcha_ajax.js小文件。這個小配置就像在Karma的配置文件中添加一行代碼那么簡單。

autoWatch確實是個很酷的設(shè)置,它會讓Karma在有文件更改時自動回歸你的測試用例。你可以這樣安裝Karma:
 

npm install karma

angular-seed 提供了一個簡單的腳本inscripts/test.sh去觸發(fā)Karma的測試。


用Jasmine設(shè)計測試用例

當使用Jasmine----一種行為驅(qū)動開發(fā)模式的JavaScript測試框架為Angular設(shè)計單元測試用例時大部分的資源都已可獲取。

這也就是我接下來要說的話題。

如果你要對AngularJS controller做單元測試可以利用Angular的依賴注入dependency injection 功能導(dǎo)入測試場景中controller需要的服務(wù)版本還能同時檢查預(yù)期的結(jié)果是否正確。例如,我定義了這個controller去高亮需要導(dǎo)航去的那個頁簽:
 

app.controller('NavCtrl', function($scope, $location) {
  $scope.isActive = function(route) {
    return route === $location.path();
  };
})

如果想要測試isActive方法,我會怎么做呢?我將檢查$locationservice 變量是否返回了預(yù)期值,方法返回的是否預(yù)期值。因此在我們的測試說明中我們會定義好局部變量保存測試過程中需要的controlled版本并在需要時注入到對應(yīng)的controller當中。然后在實際的測試用例中我們會加入斷言來驗證實際的結(jié)果是否正確。整個過程如下:
 

describe('NavCtrl', function() {
  var $scope, $location, $rootScope, createController;
 
  beforeEach(inject(function($injector) {
    $location = $injector.get('$location');
    $rootScope = $injector.get('$rootScope');
    $scope = $rootScope.$new();
 
    var $controller = $injector.get('$controller');
 
    createController = function() {
      return $controller('NavCtrl', {
        '$scope': $scope
      });
    };
  }));
 
  it('should have a method to check if the path is active', function() {
    var controller = createController();
    $location.path('/about');
    expect($location.path()).toBe('/about');
    expect($scope.isActive('/about')).toBe(true);
    expect($scope.isActive('/contact')).toBe(false);
  });
});

使用整個基本的結(jié)構(gòu),你就能設(shè)計各種類型的測試。由于我們的測試場景使用了本地的環(huán)境來調(diào)用controller,你也可以多加上一些屬性接著執(zhí)行一個方法清除這些屬性,然后再驗證一下屬性到底有沒有被清除。

$httpBackendIs Cool

那么要是你在調(diào)用$httpservice請求或是發(fā)送數(shù)據(jù)到服務(wù)端呢?還好,Angular提供了一種

$httpBackend的mock方法。這樣的話,你就能自定義服務(wù)端的響應(yīng)內(nèi)容,又或是確保服務(wù)端的響應(yīng)結(jié)果能和單元測試中的預(yù)期保持一致。

具體細節(jié)如下:
 

describe('MainCtrl', function() {
  var $scope, $rootScope, $httpBackend, $timeout, createController;
  beforeEach(inject(function($injector) {
    $timeout = $injector.get('$timeout');
    $httpBackend = $injector.get('$httpBackend');
    $rootScope = $injector.get('$rootScope');
    $scope = $rootScope.$new();
 
 
    var $controller = $injector.get('$controller');
 
    createController = function() {
      return $controller('MainCtrl', {
        '$scope': $scope
      });
    };
  }));
 
  afterEach(function() {
    $httpBackend.verifyNoOutstandingExpectation();
    $httpBackend.verifyNoOutstandingRequest();
  });
 
  it('should run the Test to get the link data from the go backend', function() {
    var controller = createController();
    $scope.urlToScrape = 'success.com';
 
    $httpBackend.expect('GET', '/slurp?urlToScrape=http:%2F%2Fsuccess.com')
      .respond({
        "success": true,
        "links": ["http://www.google.com", "http://angularjs.org", "http://amazon.com"]
      });
 
    // have to use $apply to trigger the $digest which will
    // take care of the HTTP request
    $scope.$apply(function() {
      $scope.runTest();
    });
 
    expect($scope.parseOriginalUrlStatus).toEqual('calling');
 
    $httpBackend.flush();
 
    expect($scope.retrievedUrls).toEqual(["http://www.google.com", "http://angularjs.org", "http://amazon.com"]);
    expect($scope.parseOriginalUrlStatus).toEqual('waiting');
    expect($scope.doneScrapingOriginalUrl).toEqual(true);
  });
});

正如你所見,beforeEach call其實都很類似,唯一不同的是我們是從injector獲取$httpBackend而并非直接獲取。即使如此,創(chuàng)建不同的測試時還會有一些明顯的不同之處。對初學(xué)者來說,會有一個afterEachcall 方法來確保$httpBackend在每次用例執(zhí)行后不會有明顯的異常請求。如果你觀察一下測試場景的設(shè)置和$httpBackend方法的應(yīng)用就會會發(fā)現(xiàn)有那么幾點不是那么直觀的。
 

實際上調(diào)用$httpBackend的方法也算是簡單明了但還不夠——我們還得在傳值給$scope.$apply的方法中把調(diào)用封裝到實際測試中的$scope.runTest方法上。這樣在$digest被觸發(fā)后才能處理HTTP請求。而如你所見直到我們調(diào)用$httpBackend.flush()方法后$httpBackend才會被解析,這也就保證了我們能在調(diào)用過程中去驗證返回的結(jié)果是否正確(在上面的示例中,controller的$scope.parseOriginalUrlStatusproperty屬性將被傳遞給調(diào)用者,我們也因此能實時監(jiān)控)

接下來的幾行代碼都是在調(diào)用過程中檢測$scopethat屬性的斷言。很酷吧?

提示:在某些單元測試中,用戶習(xí)慣把沒有$的范圍標記為變量。這個在Angular文檔中并沒有強制要求或是過分強調(diào),只是我在使用中為了提高可讀性和一致性才使用$scopelike這種方式。

結(jié)論

也許這就是我做起來對其他人而言只是自然而然能做到的事情之一,但是學(xué)習(xí)使用Angular編寫單元測試一開始對我而言確實是相當痛苦的。我發(fā)現(xiàn)自己對如何開始的理解大多來自互聯(lián)網(wǎng)上各種博客文章和資源的拼拼湊湊,沒有真正一致或明確的最佳實踐,而是通過自然而然隨意的選擇。我想針對我最終得到的成果提供一些文檔,以幫助那些也許還在坑里面掙扎的其他人,畢竟他們只是想要編寫代碼而已,而非不得不去了解Angular和Jasmine中所有的怪異特性和獨特用法。因此我希望這篇文章能對你有些許幫助。

相關(guān)文章

  • 談?wù)凙ngularJs中的隱藏和顯示

    談?wù)凙ngularJs中的隱藏和顯示

    本文給大家介紹angularjs 隱藏和顯示,對angularjs 隱藏和顯示相關(guān)知識感興趣的朋友一起學(xué)習(xí)吧
    2015-12-12
  • Angular.JS中指令ng-if、ng-show/ng-hide和ng-switch的使用教程

    Angular.JS中指令ng-if、ng-show/ng-hide和ng-switch的使用教程

    在Angular的原生指令中有這幾個指令用來控制元素的展示與否,ng-show/ng-hide/ng-if和ng-switch。在angular性能優(yōu)化中,我們也常常會用到它。這篇文章主要給大家介紹了在Angular.JS中指令ng-if、ng-show/ng-hide和ng-switch的使用教程,需要的朋友可以參考。
    2017-05-05
  • Angular依賴注入optional?constructor?parameters概念

    Angular依賴注入optional?constructor?parameters概念

    這篇文章主要為大家介紹了Angular?依賴注入領(lǐng)域里?optional?constructor?parameters?的概念及使用,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-11-11
  • 淺析angularJS中的ui-router和ng-grid模塊

    淺析angularJS中的ui-router和ng-grid模塊

    下面小編就為大家?guī)硪黄獪\析angularJS中的ui-router和ng-grid模塊。小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-05-05
  • AngularJs 常用的過濾器

    AngularJs 常用的過濾器

    本篇文章主要介紹了AngularJs常用的過濾器。具有很好的參考價值。下面跟著小編一起來看下吧
    2017-05-05
  • 詳解Angular 中 ngOnInit 和 constructor 使用場景

    詳解Angular 中 ngOnInit 和 constructor 使用場景

    最初學(xué)習(xí)Angular的時候總是搞不清楚ngOnInit和constructor的區(qū)別,現(xiàn)在我們來稍微理一下兩者之間的區(qū)別。
    2017-06-06
  • 淺談angular2子組件的事件傳遞(任意組件事件傳遞)

    淺談angular2子組件的事件傳遞(任意組件事件傳遞)

    今天小編就為大家分享一篇淺談angular2子組件的事件傳遞(任意組件事件傳遞),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-09-09
  • Angular 中 select指令用法詳解

    Angular 中 select指令用法詳解

    這篇文章主要介紹了Angular 中 select指令用法詳解的相關(guān)資料,本文介紹的非常詳細,具有參考借鑒價值,需要的朋友可以參考下
    2016-09-09
  • 如何利用AngularJS打造一款簡單Web應(yīng)用

    如何利用AngularJS打造一款簡單Web應(yīng)用

    如果大家希望在應(yīng)用程序的創(chuàng)建工作中采取各類最佳實踐,那么AngularJS也能夠帶來極大的助益。總而言之,這套框架的強大功能與特性永遠不會讓有著應(yīng)用開發(fā)需求的朋友們失望
    2015-12-12
  • AngularJs入門教程之環(huán)境搭建+創(chuàng)建應(yīng)用示例

    AngularJs入門教程之環(huán)境搭建+創(chuàng)建應(yīng)用示例

    這篇文章主要介紹了AngularJs入門教程之環(huán)境搭建+創(chuàng)建應(yīng)用的方法,較為詳細的分析了AngularJS的功能、下載及應(yīng)用創(chuàng)建方法,需要的朋友可以參考下
    2016-11-11

最新評論

建瓯市| 巩留县| 郧西县| 三河市| 阳新县| 会泽县| 南平市| 黎川县| 定安县| 布拖县| 巴楚县| 称多县| 临泽县| 东平县| 彭州市| 湘阴县| 荔波县| 桑日县| 巧家县| 合山市| 桐柏县| 义乌市| 界首市| 化德县| 玛纳斯县| 万安县| 黄浦区| 霞浦县| 寿宁县| 锡林浩特市| 花莲县| 灌阳县| 平乐县| 阿尔山市| 长治市| 江达县| 温州市| 黄陵县| 武平县| 望谟县| 白城市|