.callFake with $ q仍然没有输入。然后阻止

时间:2017-02-23 08:55:51

标签: javascript angularjs jasmine karma-jasmine angular-promise

我之前在其他控制器上写了几个这样的测试,它运行得很好。但是在这个更复杂的控制器上,无论我在哪个函数上进行测试,使用.callFake的{​​{1}}都没有进入$q块,因此根本没有执行任何逻辑。我知道控制器可以正常工作,因为这是在生产网站上。那么,当我退回延期承诺时,为什么我的测试甚至不会进入.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;
          }
      }
    } 
  }
})();

修改

想到了什么......这是因为我在测试中直接调用了工厂函数((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('myApp')); beforeEach(inject(function(_$controller_, _$q_, _$rootScope_, _EntryFactory_) { $controller = _$controller_; $rootScope = _$rootScope_; $scope = _$rootScope_.$new(); $q = _$q_; EntryFactory = _EntryFactory_; vm = $controller('EntryAddController', { $scope: $scope }); })); 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; }); EntryFactory.getEntryQueue(payload); $rootScope.$apply(); //expect logic in .then to have worked }); }); })(); ),而不是在它周围调用EntryFactory.getEntryQueue函数,因此它没有&是否要继续进入代码的vm.updateEntrys部分?

1 个答案:

答案 0 :(得分: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
    });
});

})();