2017-02-23 36 views
1

我已經在其他控制器上寫過一些以前的測試,它的工作原理很好。但是在這個更復雜的控制器上,無論我測試哪個函數,使用$q.callFake都沒有進入.then模塊,因此根本沒有任何邏輯被執行。我知道控制器可以正常工作,因爲這是在生產網站上。那麼,爲什麼當我返回延期承諾時,我的測試甚至不會進入.then區塊?

控制器代碼 -

(function() { 
    'use strict'; 

    angular 
    .module('myApp') 
    .controller('EntryAddController', EntryAddController); 

    function EntryAddController($scope, $state, moment, $sanitize, EntryFactory, $modal, toastr, $log) { 
    var vm = this; 
    var now = moment(); 
    var $currentYear = now.year(); 

    vm.queues = []; 
    vm.calculating = false; 
    vm.total = 0; 

    vm.saving = false; 
    vm.addTxt = 'Confirm Entry'; 

    var tomorrow = now.add(1, 'days').toDate(); 
    var to = now.subtract(1, 'days').add(12, 'months').toDate(); 

    vm.fromDate = tomorrow; 
    vm.toDate = to; 

    activate(); 

    //////////////// 

    function activate() { 

     var queueCache = {}; 

     vm.updateEntrys = function() { 

      var payload = { 
      'from': moment(vm.fromDate).format('MM/DD/YYYY'), 
      'to': moment(vm.toDate).format('MM/DD/YYYY'), 
      'freq': vm.frequency.value, 
      'total': vm.total_amount 
      }; 

      var key = JSON.stringify(payload); 

      if (!(key in queueCache)) { 

      EntryFactory.getEntryQueue(payload) 
       .then(function(resp) { 

       //LOGIC HERE BUT TEST NEVER ENTERS HERE DESPITE USING $Q 
       }); 

      } else { 

      vm.queues = queueCache[key].queue; 
      vm.total = queueCache[key].total; 
      vm.calculating = false; 
      } 
     } 
    } 
    } 
})(); 

測試代碼

編輯

只是想的東西...這是因爲我調用工廠函數(EntryFactory.getEntryQueue)直接在測試中,而不是調用它周圍的功能vm.updateEntrys,因此它不會pro切入.then部分代碼?

+1

測試中沒有'.then'塊。 '.then'塊在'vm.updateEntrys'方法中,你沒有調用,那麼你希望執行什麼'.then'塊?另外,請注意:您創造承諾的方式很難看。你可以用'return $ q.resolve(resp);'替換所有這些。 – JLRishe

+0

謝謝澄清。我被教導通過多種在線教程來創建承諾,但不知道有更好的/更清潔的方式。 – cssun25

回答

0

你總是需要考慮你的SUT(被測系統/軟件)是什麼。 在這種情況下,它是控制器的組件方法vm.updateEntrys。它調用你的Mocked EntryFactory.getEntryQueue()方法。你的代碼也不完整(你在哪裏定義了vm.frequency對象?)。儘管如此,我已通過以下測試測試了此方法:

/*property 
    $apply, $log, $modal, $new, $sanitize, $scope, $state, EntryFactory, and, 
    callFake, data, defer, getEntryQueue, moment, promise, resolve, toastr, 
    updateEntrys 
*/ 
(function() { 
    'use strict'; 

describe('Entry Add Controller Spec', function() { 

    var vm; 
    var $controller; 
    var $q; 
    var $rootScope; 
    var EntryFactory; 
    var $scope; 
    var toastr; 

    beforeEach(module('app.controllers')); 

    beforeEach(inject(function (_$controller_, _$q_, _$rootScope_) { 
     $controller = _$controller_; 
     $rootScope = _$rootScope_; 
     $q = _$q_; 

    })); 

    beforeEach(function() { 
     $scope = $rootScope.$new(); 

     EntryFactory = { 
      getEntryQueue: function() { 

      } 
     }; 

     moment = function() { 
      return { 
       format: function() { 

       } 
      } 
     } 

     vm = $controller('EntryAddController', { '$scope': $scope, '$state': {}, 'moment': moment, '$sanitize': {}, 'EntryFactory': EntryFactory, '$modal': {}, 'toastr': {}, '$log': {} }); 
    }); 

    it('expect EntryFactory.getEntryQueue to correctly set queues and total upon successful response', function() { 
     var payload = "blah"; 
     var resp = { 
      "data": 1 
     }; 

     spyOn(EntryFactory, 'getEntryQueue').and.callFake(function (payload) { 
      var deferred = $q.defer(); 
      deferred.resolve(resp); 
      return deferred.promise; 
     }); 

     vm.updateEntrys(); 

     EntryFactory.getEntryQueue(payload); 

     $scope.$apply(); 

     //expect logic in .then to have worked 
    }); 
}); 

})();

+0

謝謝!澄清了很多。 – cssun25