Angular单元测试Jasmine Spy错误 [英] Angular Unit Test Jasmine Spy error

查看:59
本文介绍了Angular单元测试Jasmine Spy错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下控制器收到TypeError:'undefined'不是一个函数(计算sessionService.getCurrentPlace()).我有一个模仿该方法的模拟服务.模拟服务上的另一种方法可以正常工作.我已经对.AndReturns({..}).AndCallThrough()做过间谍工作,但是没有运气.知道我缺少什么,还是我要解决这个错误?非常感谢!

The following controller is getting a TypeError: 'undefined' is not a function (evaluating sessionService.getCurrentPlace()). I have a Mock Service with that method being spied on. The other method on the mock service works fine. I've tried .AndReturns({..}) on the spy as well as .AndCallThrough() but no luck. Any idea what I'm missing, or am I going about this wrong? Much Thanks!

控制器:

    '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);
            });
        });
    });

单元测试:

    '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]);
        });

    });

});

推荐答案

所以我知道了.使用嵌套延迟的,您必须在两者之间调用$ scope.$ apply().以下内容对其进行了修复(对模拟数据响应进行了一些小的更改,但这些更改是微不足道的):

So I figured it out. With nested deferred's you have to call $scope.$apply() in between. The following fixed it up (along with a few minor changes to the mock data responses, but those were trivial):

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

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

这篇关于Angular单元测试Jasmine Spy错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆