成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

如何在 AngularJS 中對控制器進行單元測試

開發 前端
開發者們都一致認為單元測試在開發項目中十分有好處。它們幫助你保證代碼的質量,從而確保更穩定的研發,即使需要重構時也更有信心。

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

 

測試驅動開發流程圖

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

Instant Karma

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

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

  1. module.exports = function(config) { 
  2.     config.set({ 
  3.         basePath: '../', 
  4.  
  5.         files: [ 
  6.             'app/lib/angular/angular.js', 
  7.             'app/lib/angular/angular-*.js', 
  8.             'app/js/**/*.js', 
  9.             'test/lib/recaptcha/recaptcha_ajax.js', 
  10.             'test/lib/angular/angular-mocks.js', 
  11.             'test/unit/**/*.js' 
  12.         ], 
  13.  
  14.         exclude: [ 
  15.             'app/lib/angular/angular-loader.js', 
  16.             'app/lib/angular/*.min.js', 
  17.             'app/lib/angular/angular-scenario.js' 
  18.         ], 
  19.  
  20.         autoWatch: true, 
  21.  
  22.         frameworks: ['jasmine'], 
  23.  
  24.         browsers: ['PhantomJS'], 
  25.  
  26.         plugins: [ 
  27.             'karma-junit-reporter', 
  28.             'karma-chrome-launcher', 
  29.             'karma-firefox-launcher', 
  30.             'karma-jasmine', 
  31.             'karma-phantomjs-launcher' 
  32.         ], 
  33.  
  34.         junitReporter: { 
  35.             outputFile: 'test_out/unit.xml', 
  36.             suite: 'unit' 
  37.         } 
  38.  
  39.     }) 

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

  • 需要更改瀏覽器從Chrome 轉到PhantomJS, 這樣每次跳轉時無需再打開新的瀏覽器窗口,但在OSX系統會有窗口延遲。所以這個插件還有瀏覽器設置都做了更改。

  • 由于我的應用需要引用Google的Recaptcha服務因此添加了依賴的recaptcha_ajax.js小文件。這個小配置就像在Karma的配置文件中添加一行代碼那么簡單。

 

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

  1. npm install karma 

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

用Jasmine設計測試用例

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

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

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

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

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

  1. describe('NavCtrl', function() { 
  2.     var $scope, $location, $rootScope, createController; 
  3.  
  4.     beforeEach(inject(function($injector) { 
  5.         $location = $injector.get('$location'); 
  6.         $rootScope = $injector.get('$rootScope'); 
  7.         $scope = $rootScope.$new(); 
  8.  
  9.         var $controller = $injector.get('$controller'); 
  10.  
  11.         createController = function() { 
  12.             return $controller('NavCtrl', { 
  13.                 '$scope': $scope 
  14.             }); 
  15.         }; 
  16.     })); 
  17.  
  18.     it('should have a method to check if the path is active', function() { 
  19.         var controller = createController(); 
  20.         $location.path('/about'); 
  21.         expect($location.path()).toBe('/about'); 
  22.         expect($scope.isActive('/about')).toBe(true); 
  23.         expect($scope.isActive('/contact')).toBe(false); 
  24.     }); 
  25. }); 

使用整個基本的結構,你就能設計各種類型的測試。由于我們的測試場景使用了本地的環境來調用controller,你也可以多加上一些屬性接著執行一個方法清除這些屬性,然后再驗證一下屬性到底有沒有被清除。

#p#

$httpBackendIs Cool

那么要是你在調用$httpservice請求或是發送數據到服務端呢?還好,Angular提供了一種

$httpBackend的mock方法。這樣的話,你就能自定義服務端的響應內容,又或是確保服務端的響應結果能和單元測試中的預期保持一致。

具體細節如下:

  1. describe('MainCtrl', function() { 
  2.     var $scope, $rootScope, $httpBackend, $timeout, createController; 
  3.     beforeEach(inject(function($injector) { 
  4.         $timeout = $injector.get('$timeout'); 
  5.         $httpBackend = $injector.get('$httpBackend'); 
  6.         $rootScope = $injector.get('$rootScope'); 
  7.         $scope = $rootScope.$new(); 
  8.  
  9.  
  10.         var $controller = $injector.get('$controller'); 
  11.  
  12.         createController = function() { 
  13.             return $controller('MainCtrl', { 
  14.                 '$scope': $scope 
  15.             }); 
  16.         }; 
  17.     })); 
  18.  
  19.     afterEach(function() { 
  20.         $httpBackend.verifyNoOutstandingExpectation(); 
  21.         $httpBackend.verifyNoOutstandingRequest(); 
  22.     }); 
  23.  
  24.     it('should run the Test to get the link data from the go backend', function() { 
  25.         var controller = createController(); 
  26.         $scope.urlToScrape = 'success.com'
  27.  
  28.         $httpBackend.expect('GET', '/slurp?urlToScrape=http:%2F%2Fsuccess.com') 
  29.             .respond({ 
  30.                 "success": true, 
  31.                 "links": ["http://www.google.com", "http://angularjs.org", "http://amazon.com"] 
  32.             }); 
  33.  
  34.         // have to use $apply to trigger the $digest which will 
  35.         // take care of the HTTP request 
  36.         $scope.$apply(function() { 
  37.             $scope.runTest(); 
  38.         }); 
  39.  
  40.         expect($scope.parseOriginalUrlStatus).toEqual('calling'); 
  41.  
  42.         $httpBackend.flush(); 
  43.  
  44.         expect($scope.retrievedUrls).toEqual(["http://www.google.com", "http://angularjs.org", "http://amazon.com"]); 
  45.         expect($scope.parseOriginalUrlStatus).toEqual('waiting'); 
  46.         expect($scope.doneScrapingOriginalUrl).toEqual(true); 
  47.     }); 
  48. }); 

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

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

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

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

結論

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

原文鏈接:http://www.oschina.net/translate/how-to-unit-test-controllers-in-angularjs-without-setting-your-hair-on-fire

責任編輯:陳四芳 來源: 開源中國編譯
相關推薦

2017-12-12 13:17:36

機器學習代碼單元測試

2012-11-01 11:32:23

IBMdw

2012-11-01 11:37:05

JavaScript單元測試測試工具

2023-12-11 08:25:15

Java框架Android

2021-03-28 23:03:50

Python程序員編碼

2019-12-18 10:25:12

機器學習單元測試神經網絡

2017-01-14 23:26:17

單元測試JUnit測試

2017-01-16 12:12:29

單元測試JUnit

2013-06-04 09:49:04

Spring單元測試軟件測試

2023-07-27 08:16:51

數據訪問層項目

2017-03-23 16:02:10

Mock技術單元測試

2017-01-14 23:42:49

單元測試框架軟件測試

2024-03-29 08:03:48

單元測試流量

2009-08-19 09:00:48

單元測試框架自動化測試

2011-04-18 13:20:40

單元測試軟件測試

2020-09-30 08:08:15

單元測試應用

2011-07-13 13:13:10

域控制器活動目錄

2009-06-26 17:48:38

JSF項目單元測試JSFUnit

2021-03-24 09:30:02

Jupyter not單元測試代碼

2023-08-02 13:59:00

GoogleTestCTest單元測試
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产在线第一页 | 拍真实国产伦偷精品 | 北条麻妃视频在线观看 | av成人在线观看 | 国产日韩欧美在线 | 精品一二三区视频 | 亚洲精品视频免费 | www成人啪啪18| 欧美日韩国产精品一区 | 久久久久国产一区二区三区四区 | 亚洲欧美一区二区三区国产精品 | www.久久久久久久久久久 | 日韩欧美精品一区 | 日韩1区2区 | 色片在线观看 | 成人精品一区二区三区中文字幕 | 人人干97| 欧美中文字幕在线观看 | 亚洲最新在线视频 | 久热中文字幕 | 中文字幕一区二区三区在线观看 | 国产高清视频一区 | 日韩一区av| 欧美精品1区2区3区 精品国产欧美一区二区 | 在线国产视频 | 三级黄色片在线播放 | 日韩最新网址 | av黄色在线 | 成年免费大片黄在线观看一级 | 亚洲国产精品va在线看黑人 | av大片 | 日韩成人在线免费视频 | 亚洲国产二区 | 亚洲精品久久久久久久不卡四虎 | 欧美极品在线 | 一区二区三区四区五区在线视频 | 九色91视频 | 黄色国产在线视频 | 91九色视频 | 二区三区在线观看 | 国产又色又爽又黄又免费 |