原文地址:http://www.bradoncode.com/blog/2015/05/17/angularjs-testing-controller/
@Bradley Braithwaite javascript
上面一篇文章簡單介紹瞭如何使用 Jasmine 進行JavaScript的單元測試html
咱們用了一段簡單的代碼進行計算的測試。vue
接下來咱們將其延伸到咱們對Angular Controller的測試中。若是你不太瞭解angular也不要緊,下文也會說起關於Angular的一些知識。java
在開始寫測試以前,咱們先寫一個簡單的計算App,它會計算兩個數字之和。git
代碼以下:angularjs
<html> <head> <script type="text/javascript" src="https://code.angularjs.org/1.4.0-rc.2/angular.min.js"></script> </head> <body> <!-- This div element corresponds to the CalculatorController we created via the JavaScript--> <div ng-controller="CalculatorController"> <input ng-model="x" type="number"> <input ng-model="y" type="number"> <strong>{{z}}</strong> <!-- the value for ngClick maps to the sum function within the controller body --> <input type="button" ng-click="sum()" value="+"> </div> </body> <script type="text/javascript"> // Creates a new module called 'calculatorApp' angular.module('calculatorApp', []); // Registers a controller to our module 'calculatorApp'. angular.module('calculatorApp').controller('CalculatorController', function CalculatorController($scope) { $scope.z = 0; $scope.sum = function() { $scope.z = $scope.x + $scope.y; }; }); // load the app angular.element(document).ready(function() { angular.bootstrap(document, ['calculatorApp']); }); </script> </html>
簡單說說裏面涉及的一些基本概念:github
什麼是angular.module?它是用於建立,回收模塊的地方
。咱們建立一個名爲calculatorApp新的模塊,咱們並將組件添加到這個模塊裏。bootstrap
angular.module('calculatorApp', []);
關於第二個參數?第二個參數必須的,代表咱們正在創造一個新的模塊。若是須要咱們的應用程序有其餘的依賴,咱們能夠將它們['ngResource','ngCookies']
傳入進去。
第二個參數的存在的表示這是一個請求返回的模塊的實例。segmentfault
從概念上講,它本意是相似下面的意思:api
* angular.module.createInstance(name, requires); * angular.module.getInstance(name)
然而實際咱們是這樣寫的:
* angular.module('calculatorApp', []); // i.e. createInstance * angular.module('calculatorApp'); // i.e. getInstance
關於module的更多信息 https://docs.angularjs.org/api/ng/function/angular.module
接着咱們給angular module的示例添加一個controller
angular.module('calculatorApp').controller('CalculatorController', function CalculatorController($scope) { $scope.z = 0; $scope.sum = function() { $scope.z = $scope.x + $scope.y; }; });
控制器主要負責業務邏輯和視圖綁定,$scope
者是視圖的控制器直線的信使。
在下面 HTML 中,咱們須要計算input裏面的值,而這些都包含在這個controller的div中。
<div ng-controller="CalculatorController"> <input ng-model="x" type="number"> <input ng-model="y" type="number"> <strong>{{z}}</strong> <!-- the value for ngClick maps to the sum function within the controller body --> <input type="button" ng-click="sum()" value="+"> </div>
input 中的ng-model綁定的的值及時$scope上定義的好比$scope.x
,咱們還在button元素使用ng-click綁定了$scope.sum
方法。
接下來終於到了咱們的主題,添加一些單元測試給controller,咱們忽略代碼中html部分,主要集中在controller的代碼中。
angular.module('calculatorApp').controller('CalculatorController', function CalculatorController($scope) { $scope.z = 0; $scope.sum = function() { $scope.z = $scope.x + $scope.y; }; });
爲了測試 controller,咱們還得說起下面幾點?
如何建立一個controller實例
如何get/set一個對象的屬性
如何調用$scope裏面的函數
describe('calculator', function () { beforeEach(angular.mock.module('calculatorApp')); var $controller; beforeEach(angular.mock.inject(function(_$controller_){ $controller = _$controller_; })); describe('sum', function () { it('1 + 1 should equal 2', function () { var $scope = {}; var controller = $controller('CalculatorController', { $scope: $scope }); $scope.x = 1; $scope.y = 2; $scope.sum(); expect($scope.z).toBe(3); }); }); });
開始前咱們須要引入ngMock,咱們在測試的代碼加入angular.mock
,ngMock模塊提供了一種機制進行諸如以及虛擬的service進行單元測試。
使用ngMock咱們能夠註冊一個calculator app實例。
beforeEach(angular.mock.module('calculatorApp'));
一旦calculatorApp初始化後,咱們可使用inject
函數,這樣能夠解決controller的引用問題。
beforeEach(angular.mock.inject(function(_$controller_) { $controller = _$controller_; }));
一旦app加載完了,咱們使用了inject
函數,$controller service能夠獲取 CalculatorController 的實例。
var controller = $controller('CalculatorController', { $scope: $scope });
在上篇代碼中咱們已經能夠獲取一個controller的實例,在括號的第二個參數實際是controller本身,咱們的controller只有一個參數$scope
對象
function CalculatorController($scope) { ... }
在咱們的測試中$scope表明的就是一個簡單的JavaScript對象。
var $scope = {}; var controller = $controller('CalculatorController', { $scope: $scope }); // set some properties on the scope object $scope.x = 1; $scope.y = 2;
咱們設置x,y的值,模擬剛纔的gif中的所展現的同樣。咱們贊成也能夠讀取對象中的屬性,就像下面這段測試的斷言:
expect($scope.z).toBe(3);
最後一件事情就是咱們如何模擬用戶的點擊,就像咱們在絕大多數JS中使用的一致,,其實就是簡單的調用函數就行,
$scope.sum();
運行效果以下
本篇文章簡單的基本的介紹瞭如何對angular controller進行單元測試,可是這是創建在不停的刷新瀏覽器基礎上,
而這些流暢能夠再好,也是咱們後面的一篇文章 如何使用karam進行 angular 測試 (翻譯中...)的所要說的。
完整代碼:https://github.com/JackPu/angular-test-tutorial/blob/master/angular-test.html