对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 相关文章推荐
PJBlog插件 防刷新的在线播放器
Oct 25 Javascript
JS倒计时代码汇总
Nov 25 Javascript
详细解读AngularJS中的表单验证编程
Jun 19 Javascript
Javascript字符串拼接小技巧(推荐)
Jun 02 Javascript
详解用vue编写弹出框组件
Jul 04 Javascript
Vue 使用中的小技巧
Apr 26 Javascript
详解小程序如何避免多次点击,重复触发事件
Apr 08 Javascript
JavaScript中BOM对象原理与用法分析
Jul 09 Javascript
js实现移动端吸顶效果
Jan 08 Javascript
vue-cli4项目开启eslint保存时自动格式问题
Jul 13 Javascript
一文秒懂JavaScript构造函数、实例、原型对象以及原型链
Aug 25 Javascript
微信小程序实现打卡签到页面
Sep 21 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
php url地址栏传中文乱码解决方法集合
2010/06/25 PHP
使用迭代器 遍历文件信息的详解
2013/06/08 PHP
CodeIgniter常用知识点小结
2016/05/26 PHP
thinkphp跨库操作的简单代码实例
2016/09/22 PHP
PHP fopen中文文件名乱码问题解决方案
2020/10/28 PHP
用javascript实现计算两个日期的间隔天数
2007/08/14 Javascript
编写可维护面向对象的JavaScript代码[翻译]
2011/02/12 Javascript
JavaScript的常见兼容问题及相关解决方法(chrome/IE/firefox)
2013/12/31 Javascript
javascript实例--教你实现扑克牌洗牌功能
2014/05/15 Javascript
Javascript Objects详解
2014/09/04 Javascript
快速学习jQuery插件 Cookie插件使用方法
2015/12/01 Javascript
jQuery实现为LI列表前3行设置样式的方法【2种方法】
2016/09/04 Javascript
浅谈jquery采用attr修改form表单enctype不起作用的问题
2016/11/25 Javascript
Javascript实现倒计时时差效果
2017/05/18 Javascript
jQuery事件blur()方法的使用实例讲解
2019/03/30 jQuery
JavaScript怎样在删除前添加确认弹出框?
2019/05/27 Javascript
Vue中的循环及修改差值表达式的方法
2019/08/29 Javascript
JavaScript中的各种宽高属性的实现
2020/05/08 Javascript
VueCli生产环境打包部署跨域失败的解决
2020/11/13 Javascript
基于vue+echarts数据可视化大屏展示的实现
2020/12/25 Vue.js
使用JS实现鼠标放上图片进行放大离开实现缩小功能
2021/01/27 Javascript
[06:04]DOTA2国际邀请赛纪录片:Just For LGD
2013/08/11 DOTA
[01:45]亚洲邀请赛互动指南虚拟物品介绍
2015/01/30 DOTA
Pytorch实现将模型的所有参数的梯度清0
2020/06/24 Python
如何使用pycharm连接Databricks的步骤详解
2020/09/23 Python
英国最大的电脑零售连锁店集团:PC World
2016/10/10 全球购物
Melissa鞋马来西亚官方网站:MDreams马来西亚
2018/04/05 全球购物
思想品德课教学反思
2014/02/10 职场文书
读书活动实施方案
2014/03/10 职场文书
汽车运用工程专业求职信
2014/06/18 职场文书
2015年个人自我剖析材料
2014/12/29 职场文书
小学生组织委员竞选稿
2015/11/21 职场文书
导游词之宿迁乾隆行宫
2019/10/15 职场文书
Python中非常使用的6种基本变量的操作与技巧
2022/03/22 Python
nginx实现多geoserver服务的负载均衡
2022/05/15 Servers
详解Flutter自定义应用程序内键盘的实现方法
2022/06/14 Java/Android