角度单位测试茉莉花间谍错误

时间:2014-07-22 15:24:50

标签: angularjs unit-testing jasmine

以下控制器正在获取TypeError:'undefined'不是函数(评估sessionService.getCurrentPlace())。我有一个模拟服务,该方法被监视。模拟服务上的另一种方法工作正常。我在间谍和.AndReturns({..})上尝试.AndCallThrough()但没有运气。知道我错过了什么,还是我错了?非常感谢!

控制器:

    'use strict';

angular.module('wallyApp')
    .controller('addGatewayCtrl', function ($scope, $location, $filter, sessionService) {
        /*
            private members
        */
        //set scope from session data
        $scope.processSession = function (places) {
            $scope.currentPlaceId = sessionService.getCurrentPlace();
            if (!$scope.currentPlaceId) {
                $scope.currentPlaceId = places[0].id;
            }
            $scope.place = $filter("getById")(places, $scope.currentPlaceId);
            $scope.ready = true;
        };

        /* 
            setup our scope
        */
        $scope.currentPlaceId = null;
        $scope.place = {};
        $scope.videoSrc = "/videos/gateway-poster.gif";
        $scope.loaded = true;

        /*
            setup controller behaivors
        */

        //set video or gif to show or hide video
        $scope.setVideo = function () {
            $scope.videoSrc = "/videos/gateway.gif";
        };
        $scope.setPoster = function () {
            $scope.videoSrc = "/videos/gateway-poster.gif";
        };
        //initialize scope
        $scope.setVideo();

        //submit form
        $scope.continue = function () {
            $location.path("/setup/pair-gateway");
            return false;
        };
        //cancel
        $scope.back = function () {
            $location.path("/setup/plan-locations");
            return false;
        };
        //wifi
        $scope.gotoWifi = function () {
            $location.path("/setup/wifi");
            return false;
        };


        /*
            setup our services, etc
        */
        //get our places from the cache
        sessionService.get("places").then(function (places) {
            if (!places || places.length < 1) {
                sessionService.refreshPlaces(); //Note we don't care about the promise as our broadcast watch will pick up when ready
            } else {
                $scope.processSession(places);
            }
        }).catch(function (error) {
            //TODO:SSW Call Alert Service??
        });

        //Watch broadcast for changes
        $scope.$on("draco.placesRefreshed", function (event, data) {
            sessionService.get("places").then(function (places) {
                $scope.processSession(places);
            });
        });
    });

UNIT TEST:

    'use strict';

describe('addGatewayCtrl', function () {
    var $q,
        $rootScope,
        $location,
        $scope,
        $filter,
        mockSessionService,

        completePath = "/setup/pair-gateway",
        backPath = "/setup/plan-locations",
        wifiPath = "/setup/wifi",
        sessionDeferred,
        sessionInitDeferred,

        mockPlaces = [{ id: "0001" }];

    beforeEach(module('wallyApp'));

    beforeEach(inject(function (_$q_, _$rootScope_, _$location_, _$filter_) {
        $q = _$q_;
        $location = _$location_;
        $rootScope = _$rootScope_;
        $filter = _$filter_;
    }));

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

        mockSessionService = {
            get: function (contact) {
                sessionDeferred = $q.defer();
                return sessionDeferred.promise;
            },
            getCurrentPlace: function () {
                return mockPlaces[0].id;
            },
            refreshPlaces: function () {
                sessionInitDeferred = $q.defer();
                return sessionInitDeferred.promise;
            }
        };

        spyOn(mockSessionService, 'get').andCallThrough();
        spyOn(mockSessionService, 'getCurrentPlace').andReturn(mockPlaces[0].id);
        spyOn(mockSessionService, 'refreshPlaces').andCallThrough();

        $controller('addGatewayCtrl', {
            '$scope': $scope,
            '$location': $location,
            '$filter':$filter,
            'sessionService': mockSessionService
        });

    }));

    describe('call session service to get place data ', function () {

        //resolve our mock place and session services
        beforeEach(function () {
            //resolve mocks
            sessionDeferred.resolve(mockPlaces);

            $rootScope.$apply();
        });

        //run tests
        it('should have called sessionService get places', function () {
            expect(mockSessionService.get).toHaveBeenCalledWith("places");
        });
        it('should have called sessionService get currentPlaceId', function () {
            expect(mockSessionService.getCurrentPlace).toHaveBeenCalled();
        });
        it('should have set scope', function () {
            expect($scope.place).toEqual(mockPlaces[0]);
        });

    });

});

1 个答案:

答案 0 :(得分:0)

所以我明白了。对于嵌套的延迟,你必须在$之间调用$ scope。$ apply()。以下修正了(以及对模拟数据响应的一些小改动,但这些都是微不足道的):

        //resolve promises
        activityMessagesDeferred.resolve(mockActivityMessages);
        $rootScope.$apply();
        $rootScope.$broadcast("draco.sessionRefreshed");
        activityCountDeferred.resolve(mockActivityCount);
        $rootScope.$apply();

        placesDeferred.resolve(mockPlaces);
        activityListDeferred.resolve(mockActivities);
        $rootScope.$apply();