原文地址: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