萬盛學電腦網

 萬盛學電腦網 >> 腳本專題 >> javascript >> 在JavaScript的AngularJS庫中進行單元測試的方法

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

  這篇文章主要介紹了在JavaScript的AngularJS庫中進行單元測試的方法,主要針對AngularJS中的控制器相關,需要的朋友可以參考下

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

201562393334308.png (257×221)

  測試驅動開發流程圖

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

  Instant Karma

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

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

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 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 轉到PhantomJS, 這樣每次跳轉時無需再打開新的浏覽器窗口,但在OSX系統會有窗口延遲。所以這個插件還有浏覽器設置都做了更改。

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

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

  ?

  1npm install karma

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

  用Jasmine設計測試用例

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

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

 

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

 

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

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

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 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); }); });

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

  $httpBackendIs Cool

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

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

 

  具體細節如下:

 

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 describe('MainCtrl', function() { var $scope, $rootScope, $http
copyright © 萬盛學電腦網 all rights reserved