对Angular.js Controller如何进行单元测试


Posted in Javascript onOctober 25, 2016

一、写个简单的Angular App

在开始写测试之前,我们先写一个简单的计算App,它会计算两个数字之和。

对Angular.js Controller如何进行单元测试

代码如下:

<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>

二、简单说说里面涉及的一些基本概念:

创建一个 module

什么是angular.module?它是用于创建,回收模块的地方 。我们创建一个名为calculatorApp新的模块,我们并将组件添加到这个模块里。

angular.module('calculatorApp', []);

关于第二个参数?第二个参数必须的,表明我们正在创造一个新的模块。如果需要我们的应用程序有其他的依赖,我们可以将它们['ngResource','ngCookies']传入进去。 第二个参数的存在的表示这是一个请求返回的模块的实例。

从概念上讲,它本意是类似下面的意思:

* 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

2.给module添加controller

接着我们给angular module的示例添加一个controller

angular.module('calculatorApp').controller('CalculatorController', function CalculatorController($scope) { 
 $scope.z = 0;
 $scope.sum = function() {
 $scope.z = $scope.x + $scope.y;
 };
});

控制器主要负责业务逻辑和视图绑定,$scope者是视图的控制器直线的信使。

3.连接视图中的元素

在下面 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进行单元测试。

四、如何获取controller的实例

使用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 });

五、如何get/set一个对象的属性

在上篇代码中我们已经可以获取一个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);

六、如何调用$scope里面的函数

最后一件事情就是我们如何模拟用户的点击,就像我们在绝大多数JS中使用的一致,,其实就是简单的调用函数就行,

$scope.sum();

对Angular.js Controller如何进行单元测试

总结

本篇文章简单的基本的介绍了如何对angular controller进行单元测试,但是这是建立在不停的刷新浏览器基础上, 而这些流畅可以再好,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作带来一定的帮助,如果有疑问大家可以留言交流。

Javascript 相关文章推荐
JQuery 引发两次$(document.ready)事件
Jan 15 Javascript
jquery1.83 之前所有与异步列队相关的模块详细介绍
Nov 13 Javascript
Javascript 实现的数独解题算法网页实例
Oct 15 Javascript
控制台报错object is not a function的解决方法
Aug 24 Javascript
js和jquery分别验证单选框、复选框、下拉框
Dec 17 Javascript
JS中对数组元素进行增删改移的方法总结
Dec 15 Javascript
用director.js实现前端路由使用实例
Jan 27 Javascript
jquery获取select,option所有的value和text的实例
Mar 06 Javascript
基于node.js之调试器详解
Aug 22 Javascript
Vue + better-scroll 实现移动端字母索引导航功能
May 07 Javascript
VUE实现可随意拖动的弹窗组件
Sep 25 Javascript
JavaScript监听一个DOM元素大小变化
Apr 26 Javascript
jstree创建无限分级树的方法【基于ajax动态创建子节点】
Oct 25 #Javascript
input file上传 图片预览功能实例代码
Oct 25 #Javascript
Node.js开启Https的实践详解
Oct 25 #Javascript
Json对象和字符串互相转换json数据拼接和JSON使用方式详细介绍(小结)
Oct 25 #Javascript
利用yarn实现一个webpack+react种子
Oct 25 #Javascript
Yarn的安装与使用详细介绍
Oct 25 #Javascript
jQuery通过ajax快速批量提交表单数据
Oct 25 #Javascript
You might like
Javascript 设计模式(二) 闭包
2010/05/26 Javascript
JS中如何设置readOnly的值
2013/12/25 Javascript
javascript删除一个html元素节点的方法
2014/12/20 Javascript
JS自定义选项卡函数及用法实例分析
2015/09/02 Javascript
JavaScript中的原始值和复杂值
2016/01/07 Javascript
JavaScript事件用法浅析
2016/10/31 Javascript
jQuery树控件zTree使用方法详解(一)
2017/02/28 Javascript
JavaScrpt判断一个数是否是质数的实例代码
2017/06/11 Javascript
react.js使用webpack搭配环境的入门教程
2017/08/14 Javascript
mongoose设置unique不生效问题的解决及如何移除unique的限制
2017/11/07 Javascript
nodejs超出最大的调用栈错误问题
2017/12/27 NodeJs
bootstrap中selectpicker下拉框使用方法实例
2018/03/22 Javascript
详解Vue取消eslint语法限制
2018/08/04 Javascript
通过实例讲解JS如何防抖动
2019/06/15 Javascript
Layui 解决表格异步调用后台分页的问题
2019/10/26 Javascript
nodejs nedb 封装库与使用方法示例
2020/02/06 NodeJs
[46:59]完美世界DOTA2联赛PWL S2 GXR vs Ink 第二场 11.19
2020/11/20 DOTA
Python中的startswith和endswith函数使用实例
2014/08/25 Python
Python中super()函数简介及用法分享
2016/07/11 Python
解决Python requests 报错方法集锦
2017/03/19 Python
python如何将两个txt文件内容合并
2019/10/18 Python
Pandas DataFrame中的tuple元素遍历的实现
2019/10/23 Python
Python实现投影法分割图像示例(一)
2020/01/17 Python
Python编程快速上手——strip()函数的正则表达式实现方法分析
2020/02/29 Python
简单聊聊H5的pushState与replaceState的用法
2018/04/03 HTML / CSS
稀有和绝版书籍:Biblio.com
2017/02/02 全球购物
美国儿童玩具、装扮和玩偶商店:Magic Cabin
2018/09/02 全球购物
Python中如何定义一个函数
2016/09/06 面试题
财务会计专业毕业生自荐信
2013/10/02 职场文书
高中班长自我鉴定
2013/12/20 职场文书
保密普查工作实施方案
2014/02/25 职场文书
大班亲子运动会方案
2014/06/10 职场文书
初中成绩单评语
2014/12/29 职场文书
个人年终总结开头
2015/03/06 职场文书
Nginx 负载均衡是什么以及该如何配置
2021/03/31 Servers
html form表单基础入门案例讲解
2021/07/21 HTML / CSS