2015-02-09 83 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); 
     }); 
    });