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

一、写个简单的Angular App

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

代码如下:

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

(0)

相关推荐

  • Angular.js跨controller实现参数传递的两种方法

    前言 由于controllers之间不共享scope,如果希望在controllers之间传递参数,可能需要通过其他的方式实现,以下是当前我用到的两种在controllers之间传递参数的方法. 注:参考文章Sharing Data Between Angular Controllers 一.service 可以写一个包含get/set的service,取参数/赋参数 .factory('paramService',function(){ return { result:[], getResul

  • Angularjs中$http以post请求通过消息体传递参数的实现方法

    本文实例讲述了Angularjs中$http以post请求通过消息体传递参数的方法.分享给大家供大家参考,具体如下: Angularjs中,$http以post在消息体中传递参数,需要做以下修改,以确保消息体传递参数的正确性. 一.在声明应用的时候进行设置: var httpPost = function($httpProvider) { /******************************************* 说明:$http的post提交时,纠正消息体 ***********

  • AngularJS利用Controller完成URL跳转

    具体写法举例: 1.js定义一个controller function MyCtrl($scope, $location) { $scope.jumpToUrl = function(path) { //TODO:add code here }; } 2.html里面应用controller <div ng-controller='MyCtrl'> <button ng-click="jumpToUrl('/signin')">signin</button

  • AngularJs根据访问的页面动态加载Controller的解决方案

    用Ng就是想做单页面应用(simple page application),就是希望站内所有的页面都是用Ng的Route,尽量不用location.href,但是这样的webapp好处是很多,但是美中不足的是当你的webapp随着时间的推移,用户变多,功能变得更丰富,controller也变得越来越多,你不得不把所有的controller当作全局模块进行加载,以使得在站内任何一个页面中按F5刷新后能route到任意一个其他页面,而不会发生找不到controller的错误,加载所有的control

  • AngularJS出现$http异步后台无法获取请求参数问题的解决方法

    本文实例讲述了AngularJS出现$http异步后台无法获取请求参数问题的解决方法.分享给大家供大家参考,具体如下: angular在通过异步提交数据时使用了与jQuery不一样的请求头部和数据序列化方式,导致部分后台程序无法正常解析数据. 原理分析(网上的分析): 对于AJAX应用(使用XMLHttpRequests)来说,向服务器发起请求的传统方式是:获取一个XMLHttpRequest对象的引用.发起请求.读取响应.检查状态码,最后处理服务端的响应.整个过程示例如下: var xmlht

  • 解决angular的$http.post()提交数据时后台接收不到参数值问题的方法

    写此文的背景:在学习使用angular的$http.post()提交数据时,后台接收不到参数值,于是查阅了相关资料,寻找解决办法. 写此文的目的:通过上面提到的文章中的解决之道,结合自己的经验,总结了如下发现. 前端:html,jquery,angular 后端:java,springmvc 一.平常使用的post提交和接收方式 前端使用jquery提交数据. $.ajax({ url:'/carlt/loginForm', method: 'POST', data:{"name":&

  • AngularJS中一般函数参数传递用法分析

    本文实例讲述了AngularJS中一般函数参数传递用法.分享给大家供大家参考,具体如下: 1. 模型参数 直接使用变量名,不要加引号 <!doctype html> <html ng-app="passAter"> <head> <meta charset="utf-8"/> </head> <body> <div ng-controller="passCtrl">

  • 解决angular的post请求后SpringMVC后台接收不到参数值问题的方法

    这是我后台SpringMVC控制器接收isform参数的方法,只是简单的打出它的值: @RequestMapping(method = RequestMethod.POST) @ResponseBody public Map<String, Object> save( @RequestParam(value = "isform", required = false) String isform) { System.out.println("isform value

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

    一.写个简单的Angular App 在开始写测试之前,我们先写一个简单的计算App,它会计算两个数字之和. 代码如下: <html> <head> <script type="text/javascript" src="https://code.angularjs.org/1.4.0-rc.2/angular.min.js"></script> </head> <body> <!-- T

  • Angular.Js的自动化测试详解

    本文着重介绍关于ng的测试部分,主要包括以下三个方面: 框架的选择(Karma+Jasmine) 测试的分类和选择(单元测试 + 端到端测试) 在ng中各个模块如何编写测试用例 下面各部分进行详细介绍. 测试的分类 在测试中,一般分为单元测试和端到端测试,单元测试是保证开发者验证代码某部分有效性的技术,端到端(E2E)是当你想确保一堆组件能按事先预想的方式运行起来的时候使用. 其中单元测试又分为两类: TDD(测试驱动开发)和BDD(行为驱动开发). 下面着重介绍两种开发模式. TDD(测试驱动

  • Angular.js中ng-include用法及多标签页面的实现方式详解

    前言 大家在平时的项目开发中,应该会经常遇到上图所示的需求,就是在一个页面中有多个标签,被选中的标签颜色会高亮显示,切换不同标签显示相应的不同内容.如果内容代码过多则写在同一个html文件就会显得特别乱,所以这里我们最好把页面代码分开单独管理,controller也可以分开来管理,这样就会显得清楚的多. 这里就要使用到Angularjs中个ng-include指令.下面来看看详细的介绍: 一.多标签的编写 首先需要了解需求: 1.同时只能选中一个标签 2.被选中的标签背景色以及自体颜色都将改变.

  • Angular js 实现添加用户、修改密码、敏感字、下拉菜单的综合操作方法

    小编在上篇文章给大家介绍了AngularJS模糊查询功能实现代码(过滤内容下拉菜单排序过滤敏感字符验证判断后添加表格信息),今天给大家介绍Angular js 实现添加用户.修改密码.敏感字.下拉菜单的综合操作方法,具体内容如下所示: 废话不多说了,直接给大家贴代码了,具体代码如下所示: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <

  • angular.js实现购物车功能

    本文实例为大家分享了angular.js购物车功能的具体代码,供大家参考,具体内容如下 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>购物车</title> <script src="angularjs/angular.js"></script> <st

  • Angular.js实现获取验证码倒计时60秒按钮的简单方法

    前言 本文主要介绍了关于Angular.js实现获取验证码倒计时60秒按钮的相关内容,关于这个功能相信不用多介绍,大家都不陌生,所以下面话不多说了,来一起看看实现的方法吧. 一.controller中代码 angular.module('controllers') .controller('LoginCtrl', function ($scope, $location,$ionicLoading,$rootScope,$interval,$timeout) { $scope.timer = fa

  • Angular.js实现多个checkbox只能选择一个的方法示例

    首先来看看效果 效果 实现这样的效果,必须使用指令了,只有使用指令才能单独控制每一个scope. 示例代码如下: <div class="form-group"> <label class="col-sm-2 control-label">请选择文章主题色彩</label> <div class="col-sm-10" theme-group> <label class="i-swi

  • Angular.js实现注册系统的实例详解

    前言 相信大家在做项目里经常需要登录注册,那么在用angularjs该如何实现.下面让我们通过angualr.js来实现注册系统表单验证. Angular下载地址:https://code.angularjs.org/1.5.0/angular.js 首先看一下页面效果(通过bootstrap实现的布局样式): 当我们点击提交按钮时,会根据表单验证,若通过,则没有提示语句,若不通过,则会弹出响应提示语句,当然该功能可以通过其他简单方式实现,这里只是通过实战对angular进一步深入理解. 实现方

  • angular.js分页代码的实例

    对于大多数web应用来说显示项目列表是一种很常见的任务.通常情况下,我们的数据会比较多,无法很好地显示在单个页面中.在这种情况下,我们需要把数据以页的方式来展示,同时带有转到上一页和下一页的功能.现在在学习angular,使用angularjs 分页,基于 directive 实现,样式使用的 bootstrap,直接在 html代码中加入 标签即可调用. 先来看下效果图 实例代码 app.directive('pagePagination', function(){ return { rest

  • Angular.js中$resource高大上的数据交互详解

    本文主要给大家介绍的是关于Angular.js中$resource数据交互的相关内容,分享出来供大家参考学习,下面来一起看看详细的介绍: $resource 创建一个resource对象的工厂函数,可以让你安全的和RESFUL服务端进行数据交互. 需要注入 ngResource 模块.angular-resource[.min].js 默认情况下,末尾斜杠(可以引起后端服务器不期望出现的行为)将从计算后的URL中剥离. 这个可以通过$resourceProvider配置: app.config(

随机推荐