测试调用服务返回promise的Angular Controller

时间:2014-11-11 15:12:37

标签: javascript angularjs unit-testing jasmine

我正在尝试测试一个依赖于服务的角度控制器,并且服务方法返回promise。我正在创建一个jasmine间谍对象来模拟服务和返回promise的方法。但出于某种原因,我的模拟承诺并未返回已解决的结果。

这是我的控制器和服务代码。

(function(){
'use strict';
angular
    .module("supportPortal",[])
    .service('TipsService' ,['$http' ,TipsService])
    .controller('TipsCtrl', [ 'TipsService', TipsCtrl]);

function TipsService($http) {
    this.path = 'api/bondtipsfactor';
    this.tipsFactors = [];
    this.getMinMaxDates = getMinMaxDates;
    this.getData = getData;

    function getMinMaxDates() {

        var self = this;
        var promise = $http.get(self.path + '/minmaxdate').then(function (result) {
            return result.data;
        });
        return promise;
    }
}

function TipsCtrl(TipsService) {
/* jshint validthis:true */

 var vm = this,
 svc = TipsService;
 vm.title = 'TipsCtrl';
 vm.setMonths = setMonths;
 var today = new Date();
 vm.minMonth = 1;
 vm.minYear = today.getFullYear();
 vm.maxYear = today.getFullYear();
vm.maxMonth = today.getMonth() + 1;
vm.years = [];
vm.months = [];
vm.selectedYear = 2014;
vm.selectedMonth;
activate();
function activate() { 
    svc.getMinMaxDates().then(function (data) {
        console.log(data);
        var minDate = new Date(data.MinDate),
                maxDate = new Date(data.MaxDate);
        maxDate.setMonth(maxDate.getMonth() + 1);
    vm.minMonth = minDate.getMonth();
    vm.minYear = minDate.getFullYear();
    vm.maxMonth = maxDate.getMonth();
    vm.maxYear = maxDate.getFullYear();
    for (var i = vm.minYear; i <= vm.maxYear; i++) {
      vm.years[i - vm.minYear] = i;
    }
  });
}

function setMonths(year) {
    var startMonth = year === vm.minYear? vm.minMonth: 1,
            endMonth = year === vm.maxYear ? vm.maxMonth : 12;
    vm.month=[];
    for (var i = startMonth; i <= endMonth; i++) {
        vm.months[i - startMonth] = i;
    }
}
}
})();

这是测试代码

describe("TipsCtrlSpec", function () {
describe("TipsCtrl", function () {

    var ctrl, service, $q, $controller;
    beforeEach(angular.mock.module("supportPortal", function($provide) {
        service = jasmine.createSpyObj("TipsService", ['getMinMaxDates']);
        $provide.value("TipsService", service);
    }));

    beforeEach(inject(function (_$controller_, _$q_, _TipsService_) {
        service = _TipsService_;
        $q = _$q_;
        $controller = _$controller_;
    }));

    function createController(resolve)
    {
        var deferred = $q.defer();
        service.getMinMaxDates.and.returnValue(deferred.promise);
        ctrl = $controller("TipsCtrl", {
            TipsService: service
        });
        if (resolve) {
            deferred.resolve({
                MinDate: "01/01/2013",
                MaxDate: "01/01/2014"
            });
        } else {
            deferred.reject();
        }
    }

    it("activate sets min max dates", function () {
        createController(true);
        expect(ctrl).toBeDefined();
        expect(service.getMinMaxDates).toHaveBeenCalled();
        expect(ctrl.minYear).toBe(2013);
    })
});
});

以下是live code

1 个答案:

答案 0 :(得分:2)

当使用ngMock进行单元测试时,您需要同步维护测试流程并手动触发摘要周期以实现承诺实际返回。

您可以通过调用$rootScope.$digest()

来执行此操作
it("activate sets min max dates", function() {
  createController(true);
  $rootScope.$digest();
  expect(ctrl).toBeDefined();
  expect(service.getMinMaxDates).toHaveBeenCalled();
  expect(ctrl.minYear).toBe(2013);
});

演示: http://plnkr.co/edit/vWs1Dx0bjXsdrWCJKWh9?p=preview