zoukankan      html  css  js  c++  java
  • AngularJS 单元测试 Karma jasmine

      当AngularJS项目越来越大时候,需要进行单元测试,可以先开发功能再进行测试,也可以先进行测试。

    一、karma 

      是一个基于Node.js(先要安装)的JavaScript测试执行过程管理工具(Test Runner)。Test Runner是用来跑测试的工具,即,写好测试,让它跑起来。

      可用于测试所有主流Web浏览器,也可集成到CI(Continuous integration)工具,也可和其他代码编辑器一起使用。

      一个强大特性就是,可以监控(Watch)文件的变化,然后自行执行,通过console.log显示测试结果。

    二、jasmine

      是一个用于JS代码测试的行为驱动开发的框架,它不依赖于任何其他的JS框架以及DOM,是一个简洁及友好的API测试库。

      是代码中用来写断言的库,测试代码中expect和toBe等函数都来自它。

    三、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写复杂业务逻辑,给出固定数据,返回固定数据。

    四、jasmine语法

    1、一个测试用例以describe函数来定义,它有两参数,第一个用来描述测试内容,第二个参数是一个函数,写一些真实的测试代码。

    2、it是用来定义单个具体测试任务,也有两个参数,第一个用来描述测试内容,第二个参数是一个函数,里面存放一些测试方法。

    3、expect主要用来计算一个变量或者一个表达式的值、然后用来跟期望的值比较或者做一些其它的事件。

    4、beforeEach与afterEach主要是用来在执行测试任务之前和之后做一些事情,上面的例子就是在执行之前改变变量的值,然后在执行完成之后重置变量的值。

    另外,describe函数里的作用域跟普通JS一样都是可以在里面的子函数里访问的,就像上面的it访问foo变量。

    五、例子

    1、测试一个服务

      一个服务:

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

    2、模拟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'});
        }));
  • 相关阅读:
    鼠标拖拽UserChromeJS脚本在线生成器
    Firefox书签转按钮UserChromeJS脚本在线生成器
    [原创]Firefox扩展
    F5和CTRL+F5的区别
    玩转log4j
    xml文件报错之Invalid byte 1 of 1byte UTF8 sequence.
    javascript 事件
    jdbc封装类(连接参数配置与web.xml)
    浅谈DHTML
    基于servlet+smartUpload的文件上传
  • 原文地址:https://www.cnblogs.com/shawnhu/p/8487685.html
Copyright © 2011-2022 走看看