2014-02-13 79 views
0

我对测试javascript很新。我的应用程序使用angularjs。我正在使用茉莉花作为测试框架。Angularjs和Jasmine:用服务测试控制器让Ajax调用

这里是我的测试控制器:

angular.module('logonController', ["ngval", "accountFactory"]) 
    .controller("logonController", function logOnController(accountFactory, $scope, $window) { 
     $scope.hasServerError = false; 
     $scope.Logon = function() { 
      accountFactory.Logon($scope.data.LogOnModel) 
       .then(function (data) { 
        $window.location.href = "/"; 
       }, 
       function (data) { 
        $scope.hasServerError = true; 

       }); 
     } 

    }) 

其中accountFactory.Logon正在POST请求到服务器。 window.location.href叫

  • 在错误$scope.hasServerError是到目前为止,我有设置为true
  • -

    1. 在成功:

      我想测试调用accountFactory.Logon当设法做到这一点:

      "use strict"; 
      
      describe("Logon Controller", function() { 
      
          var $scope, $location, $rootScope, $httpBackend, $controller, $window, createController; 
      
          beforeEach(function() { 
           module("logonController"); 
          }); 
      
          beforeEach(inject(function ($injector) { 
           $rootScope = $injector.get("$rootScope"); 
           $scope = $rootScope.$new(); 
           $location = $injector.get("$location"); 
           $httpBackend = $injector.get("$httpBackend"); 
           $controller = $injector.get("$controller"); 
           $window = $injector.get("$window"); 
          })); 
      
          beforeEach(function() { 
           createController = function() { 
            return $controller("logonController", { 
             "$scope": $scope, 
            }); 
           }; 
      
           $scope.data = { 
            LogOnModel: { username: "user", password: "pass" } 
           }; 
      
           $window = { location: { href: jasmine.createSpy() } }; 
          }); 
      
          it("should redirect on successfull login", function() { 
           var controller = createController(); 
      
           $httpBackend.whenPOST("/Account/Logon").respond(function (method, url, data, headers) { 
            return [200, {}, {}]; 
           }); 
      
           $scope.Logon(); 
      
           $httpBackend.flush(); 
      
           expect($window.location.href).toHaveBeenCalled(); 
          }); 
      }); 
      

      我的想法是创造在$ window.location.href上检测一个间谍,并只检查它是否被调用。但我越来越

      预计的间谍未知被调用。

      正如我所说我很新的测试JavaScript,所以任何帮助将不胜感激。

    回答

    -1

    你需要创建一个间谍:

    spyOn($window, 'location.href').andCallThrough(); 
    

    但在一个更大的注,虽然,你不应该在控制器测试来测试你的服务的功能。

    3

    斯登Muchow的答案是错在几个方面:

    1. 你不能指定复合属性名(“location.href”)为第2参数spyOn。你必须提供一个不动产名称。
    2. 即使您正确地执行spyOn,并且CallThrough()仍然会引发异常,因为$ window.location.href不是可以调用的函数。

    但他仍然正确地说你不应该将控制器测试与服务测试混为一谈。

    要回答这个问题:

    的原因,你的期望没有得到满足(连狙仍然存在*)是,你正在做的$ window.location.href分配中承诺的那么()函数。这意味着,它将被异步执行,即在expect()调用之后执行。为了解决这个问题,你需要使测试工作异步(对于如何做到这一点,我想告诉你Jasmine文档:http://jasmine.github.io/2.0/introduction.html)。

    *在accountFactory.Logon中,通过执行$window.location.href =(即转让),您将有效覆盖您的间谍。

    更好的解决方案:

    而是操纵$window.location.href的,你应该使用$location.url()

    $location是一个Angular核心服务。您将受益于角应用程序生命周期内的积分+它无缝地与现有的HTML5 API,如历史API集成(即观察家将当URL变化来自动处理):https://docs.angularjs.org/guide/ $位置

    然后,您可以在$间谍location.url()就像你在$ window.location.href(如果它已经是一个函数)上窥探的一样。

    相关问题