2015-02-09 73 views
1

我在设置测试包含承诺的Angular控制器时遇到了一些麻烦。使用Jasime测试角度控制器的承诺

控制器代码是这样的:

angular.module('jhApp') 
.controller('adminPagesCtrl', function(resourceCache) { 
    var adminPages = this; 
    adminPages.items = resourceCache.query('page'); 

    adminPages.delete = function(page) { 
     resourceCache.delete('page', {id:page._id}) 
     .then(function(responceData) { 
      if(responceData.deleted === true) { 
       adminPages.items = resourceCache.query('page'); 
      } 
     }); 
    }; 
}); 

我的测试是这样的:

describe('adminPagesCtrl', function() { 
    var defferred, 
     $rootScope, 
     controller, 
     resourceCache, 
     scope, 
     page, 
     defferred, 
     promise; 

    beforeEach(function() { 
     module('jhApp'); 
    }); 

    beforeEach(inject(function ($rootScope, $controller, $q) { 
     scope = $rootScope.$new(); 
     controller = $controller('adminPagesCtrl as adminPages', {$scope: scope}); 
     deffered = $q.defer(); 
     promise = deffered.promise; 

     resourceCache = { 
      delete: promise 
     }; 
     page = {_id: 1}; 
     spyOn(resourceCache, 'delete'); 

    })); 

    it('deletes a page', function() { 
     expect(controller).toBeDefined(); 
     scope.adminPages.delete(page); 
     console.log(resourceCache.delete) //outputs: function{} 
     console.log($rootScope) //outputs: undefined 
     resourceCache.delete.resolve({deleted: true}); 
     $rootScope.$apply(); 
     expect(resourceCache.delete).toHaveBeenCalled(); 
    }); 
}); 

我试图嘲弄resourceCache承诺,因此返回一些假的数据,所以我可以测试返回了一些东西,并且adminPages.delete调用了resourceCache.delete。 我觉得我做的根本错误,虽然作为当前错误的东西:

undefined is not a fuction 

这我相信,是因为如果我尝试登录了resourceCache.delete它只是显示空功能。第一个期望

resourceCache.delete.resolve(); 

通过确定。

回答

1

您需要将resourceCache.delete设置为返回承诺而不是仅设置为承诺的函数。你也应该嘲笑resourceCache.query。要解决该承诺,需要在调用controller.delete后使用deffered.resolve(response);。然后$rootScope.$digest();

describe('adminPagesCtrl', function() { 
    var createController, $rootscope, deferred, resourceCache; 

    beforeEach(module('jhApp')); 

    beforeEach(inject(function($controller, _$rootScope_, $q) { 
    $rootScope = _$rootScope_; 
    deferred = $q.defer(); 

    resourceCache = { 
     delete: function() { 

     }, 
     query: function (page) { 

     } 
    }; 

    spyOn(resourceCache, 'delete').and.returnValue(deferred.promise); 

    createController = function() { 
      return $controller('adminPagesCtrl', { resourceCache: resourceCache }); 
    }; 

    })); 

    it('deletes a page', function() { 
    //Arrange 
    var controller = createController(); 
    var page = { 
     _id: 1 
    }; 

    var response = { 
     deleted: true 
    }; 

    var items = [{ 
     test: 'test' 
    }]; 

    var expectedDeleteParam = { 
     id: page._id 
    }; 

    spyOn(resourceCache, 'query').and.returnValue(items); 

    //Act 
    controller.delete(page); 
    deferred.resolve(response); 
    $rootScope.$digest(); 

    //Assert 
    expect(resourceCache.delete).toHaveBeenCalledWith('page', expectedDeleteParam); 
    expect(resourceCache.query).toHaveBeenCalledWith('page'); 
    expect(controller.items).toEqual(items); 
    }); 
}); 

Plunkr

+0

如果我只打电话给第一个预期并删除$ rootScope。$ digest,现在工作情况会好一些。如果我在第一次保存$ rootScope摘要期望失败错误:意外的请求:尝试加载其中一个项目html模板的GET。其他两种期望也会使测试失败 – 2015-02-10 21:25:25

+0

为什么在测试中加载html模板? – 2015-02-10 21:26:53

+0

我没想到我正在加载模板。如果我有,那么它不是故意 – 2015-02-10 21:34:49

0

我终于得到这个工作,所以如果任何人有类似的问题,这里是修订后的版本。调用$ rootScope.digest()与Karma导致错误。

Error: Unexpected request: GET views/projects.html 
    No more request expected 

我换了那个作用域= $ rootScope。$ new();现在测试正在通过。

describe('adminPagesCtrl', function() { 
     var createController, $rootScope, deferred, resourceCache, scope; 

     beforeEach(module('jhApp')); 

     beforeEach(inject(function($controller, $rootScope, $q) { 
     scope = $rootScope.$new(); 
      deferred = $q.defer(); 

     resourceCache = { 
      delete: function() { 

      }, 
      query: function (page) { 

      } 
     }; 

     spyOn(resourceCache, 'delete').and.returnValue(deferred.promise); 

     createController = function() { 
      return $controller('adminPagesCtrl', { resourceCache: resourceCache }); 
     }; 
     })); 

     it('deletes a page', function() { 
     //Arrange 
     var controller = createController(); 
     var page = { 
      _id: 1 
     }; 

     var response = { 
      deleted: true 
     }; 

     var items = [{ 
      test: 'test' 
     }]; 

     var expectedDeleteParam = { 
      id: page._id 
     }; 

     spyOn(resourceCache, 'query').and.returnValue(items); 

     //Act 
     controller.delete(page); 
     deferred.resolve(response); 
     scope.$digest(); 

     //Assert 
     expect(resourceCache.delete).toHaveBeenCalledWith('page', expectedDeleteParam); 
     expect(resourceCache.query).toHaveBeenCalledWith('page'); 
     expect(controller.items).toEqual(items); 
     }); 
    });