当AngularJS项目愈来愈大时候,须要进行单元测试,能够先开发功能再进行测试,也能够先进行测试。后端
1、karma 浏览器
是一个基于Node.js(先要安装)的JavaScript测试执行过程管理工具(Test Runner)。Test Runner是用来跑测试的工具,即,写好测试,让它跑起来。服务器
可用于测试全部主流Web浏览器,也可集成到CI(Continuous integration)工具,也可和其余代码编辑器一块儿使用。网络
一个强大特性就是,能够监控(Watch)文件的变化,而后自行执行,经过console.log显示测试结果。app
2、jasmine框架
是一个用于JS代码测试的行为驱动开发的框架,它不依赖于任何其余的JS框架以及DOM,是一个简洁及友好的API测试库。异步
是代码中用来写断言的库,测试代码中expect和toBe等函数都来自它。编辑器
3、mock库函数
angular-mocks.js 是一个AngularJS提供的一个用来Mock内置服务的独立测试库。如对$httpBackend,$exceptionHandler。工具
$httpBackend 经过本地调用来模拟服务器对象。模拟http后端,即服务器。
$httpBackend.whenGet("/someUrl").respond({name:'wolf'},{'X-Record-Count':100'});
即,声明了一个模拟服务端,当测试代码请求Get/someUrl地址时候,被$httpBackend拦截,并返回一个JSON对象{name:'wolf'},同时,返回一个额外的response header : X-Record-Count 值为100.
另外,须要$httpBackend.flush函数触发调用。并且,不要在mock写复杂业务逻辑,给出固定数据,返回固定数据。
4、jasmine语法
一、一个测试用例以describe函数来定义,它有两参数,第一个用来描述测试内容,第二个参数是一个函数,写一些真实的测试代码。
二、it是用来定义单个具体测试任务,也有两个参数,第一个用来描述测试内容,第二个参数是一个函数,里面存放一些测试方法。
三、expect主要用来计算一个变量或者一个表达式的值、而后用来跟指望的值比较或者作一些其它的事件。
四、beforeEach与afterEach主要是用来在执行测试任务以前和以后作一些事情,上面的例子就是在执行以前改变变量的值,而后在执行完成以后重置变量的值。
另外,describe函数里的做用域跟普通JS同样都是能够在里面的子函数里访问的,就像上面的it访问foo变量。
5、例子
一、测试一个服务
一个服务:
angular.module("app.services").service("constService", function(){ this.myConstanat = 2; });
编写测试(jasmine)
describe("constService", function () { var out; // 被测对象 beforeEach(function () { module('app.services'); // 导入模块 inject(function (constService) { // 注入依赖 out = constService; // 关联被测对象实例 })); it("one == 1", function () { expect(out.myConstant).toEqual(1); }); });
二、模拟http请求返回值
通常咱们写$http请求,用以下代码到服务器端请求,函数经过http get请求获得user的值。
//经过http请求获得user $scope.GetUser = function(){ $http.get('/auth.py').then(function(response) { $scope.user = response.data; });
单元测试里咱们并不真的但愿发送一个http get请求来运行测试,由于那样会使测试复杂化,网络相关的各类问题都会致使测试失败,并且angular http服务是异步的,而咱们但愿测试是同步的。
var scope,ctrl; //inject利用angular的依赖注入,将须要的模块,服务插入做用域 beforeEach(inject(function ($controller, $rootScope) { //模拟生成scope, $rootScope是angular中的顶级scope,angular中每一个controller中的 //scope都是rootScope new出来的 scope = $rootScope.$new(); //模拟生成controller 并把先前生成的scope传入以方便测试 ctrl = $controller('unitTestCtrl', {$scope: scope}); })); //开始测试 //模拟http get的返回值, 插入injector服务,让咱们可以在测试代码中使用依赖注入来得到须要的服务 it('GetUser should fetch users', inject(function($injector){ // $httpBackend 是由angular mock提供的一个模拟http请求返回服务 // 能够用它来模拟http请求的返回值 // 这里经过$injector来获取它的实例 var $httpBackend = $injector.get('$httpBackend'); // $httpBackend 在Get方法,对 '/auth.py' 的url将会返回 一个jason对象 // {customerId: '1',name:'benwei'} $httpBackend.when('GET', '/auth.py').respond({customerId: '1',name:'benwei'}); //以上为测试前的准备工做, 也能够把这部分代码放在beforeEach里, //但要注意: beforeEach里的设置将影响全部在它做用域的测试用例。 //运行GetUser函数 scope.GetUser(); //把http的异步转为同步,要求$httpBackend马上返回数据 $httpBackend.flush(); // 查看scope.user的值是否正确 expect(scope.user).toEqual({customerId: '1',name:'benwei'}); }));