角度模态控制器测试误差



我很难尝试测试模态控制器(使用Angular UI Bootstrap创建)。我尽可能地降低了测试代码,但我仍然收到错误。这是模态控制器(其中的一部分):

var controllersModule = angular.module('forge.geomanagement.controllers');
controllersModule.controller('EditGeofenceModalController', function ($timeout, $scope: , $modalInstance, forgeGeoTriggerService, $rootScope, geofence, triggerID) {
  var searchAddressInput: HTMLInputElement;
  //make a copy of geofence obj passed into modal
  $scope.geofence = {
    FriendlyName: geofence.FriendlyName,
    Coords: angular.copy(geofence.Boundary),
    GeoTags: angular.copy(geofence.GeoTags)
  };
  $scope.goefenceID = triggerID;
  var gCLength = $scope.geofence.Coords.length;
  //wrap it in timeout function to paint the map after its container is rendered
  $timeout(function () { 
    $scope.geofenceMap = new google.maps.Map(document.getElementById('map_canvas'),  $scope.mapOptions);
    //autocomplete functionality
    searchAddressInput = <HTMLInputElement>document.getElementById('pac-input');
    $scope.autocomplete = new google.maps.places.Autocomplete(searchAddressInput, $scope.mapOptions);
    $scope.autocomplete.bindTo('bounds', $scope.geofenceMap); //set autocomplete suggestion bounds to map's current viewport
    //bind autocomplete to the map
    google.maps.event.addListener($scope.autocomplete, 'place_changed', function () {
        $scope.place = $scope.autocomplete.getPlace();
        $scope.geofenceMap.panTo($scope.place.geometry.location);
        $scope.geofenceMap.setZoom(12);
        $scope.model.searchAddress = $scope.place.formatted_address;
        $scope.$digest();
    });
    //GEOFENCE FUNCTIONALITY
    forgeGeoTriggerService.GeofenceCreator($scope.geofenceMap, $scope.geofence.Coords);
    //show geofence in edit mode
    forgeGeoTriggerService.ShowGeofence($scope.geofenceMap, $scope.geofence.Coords);
    $scope.$on("polygonPath.updated", function (event, geofenceCoords) {
        $scope.$apply(function () {
            $scope.geofence.Coords = geofenceCoords;
        });
    });
    //clear geofence area btn
    $scope.clearGeofenceArea = function () {
        forgeGeoTriggerService.ClearGeofenceArea();
        $scope.geofence.Coords.length = 0; // clear geofence array
    };
}, 0);
$scope.cancel = function () {
    $modalInstance.close()
};
$scope.saveGeofence = function () {
    forgeGeoTriggerService.EditGeofence($scope.geofence, $scope.goefenceID)
        .then(function (data) {
            $scope.successMessage = 'Geofence Updated Successfully'
            $rootScope.$broadcast('geotrigger.edited');
            $timeout(function () {
                $modalInstance.close();
            }, 2000);
        }, function (data) {
            $scope.errorMessage = 'There was an error when updating geofence. Please try again.';
        });
}

});

这是模态控制器测试

describe("forge.geomanagement.GeoApp", function () {
var scope, controller, modalInstance, timeout, forgeGeoTriggerService, window = {},
    geofencemock, geofence, triggerID;
beforeEach(module('forge.geomanagement.GeoApp'));
describe("Controller: EditGeofenceModalController", function () {
    beforeEach(inject(function ($controller, $rootScope, $timeout, _forgeGeoTriggerService_) {
        scope = $rootScope.$new();
        timeout = $timeout;
        modalInstance = { 
            close: jasmine.createSpy('modalInstance.close'),
            dismiss: jasmine.createSpy('modalInstance.dismiss'),
            result: {
                then: jasmine.createSpy('modalInstance.result.then')
            }
        }
        geofencemock = {
            FriendlyName: 'mock geofence',
            Coords: [
                {
                    "lat": 53.5598889724547,
                    "lng": -6.36953830718994
                },
                {
                    "lat": 53.463525599115,
                    "lng": -6.53707981109619
                },
                {
                    "lat": 53.3685818160803,
                    "lng": -6.46841526031494
                },
                {
                    "lat": 53.384966558115,
                    "lng": -5.75430393218994
                },
                {
                    "lat": 53.5598889724547,
                    "lng": -6.34756565093994
                },
                {
                    "lat": 53.5598889724547,
                    "lng": -6.36953830718994
                }
            ],
            GeoTags: ['tag1','tag2','tag3']
        }
        triggerIDmock = 1;
        forgeGeoTriggerService = _forgeGeoTriggerService_;
        controller = $controller("EditGeofenceModalController", {
            $scope: scope,
            $timeout: timeout,
            $modalInstance: modalInstance,
            forgeGeoTriggerService: forgeGeoTriggerService,
            geofence: geofencemock,
            triggerID: triggerIDmock
        });
    }));
    it('2 is 2', function () {
        expect(2).toBe(2);
    })
    it("geofence should be defined", function () {
        expect(geofencemock).toBeDefined();
    });
    it("should contain reference to forgeGeoTriggerService", function () {
        expect(forgeGeoTriggerService).not.toBeNull();
    });
    it("$modalInstance obj should be defined when modal is open", function () {
        expect(modalInstance).toBeDefined();
    });
    it("cancel function should close edit geofence modal", function () {
        scope.cancel();
        expect(modalInstance.close).toHaveBeenCalled();
    });
});

});

但是当我尝试运行它时,我收到错误:"无法读取未定义的属性长度",对应于 $scope.geofence.Coords 属性 - 一个从父控制器成功复制到模态的数组。如您所见,我还创建了一个geofencemock对象,并尝试在非常简单的测试中使用它,但看起来它没有被拾取。我真的很感激一些意见,因为我已经花了几个小时试图修复它或在线找到解决方案,但无济于事。

谢谢。

您正在从geofence.Boundary设置$scope.geofence.Coords

$scope.geofence = {
  FriendlyName: geofence.FriendlyName,
  Coords: angular.copy(geofence.Boundary),
  GeoTags: angular.copy(geofence.GeoTags)
};

但你直接用Coords嘲笑geofence

geofencemock = {
  FriendlyName: 'mock geofence',
  Coords: [
    {
      "lat": 53.5598889724547,
      "lng": -6.36953830718994
    },

将后者更改为geofencemock.Boundary,您应该没问题。

好的,我让它工作了。错误"无法读取未定义的属性'lat'"与地理围栏模拟对象中的坐标无关,而与地理围栏有关。我在带有地理围栏的控制器中使用的 Center.lat 属性。Center.lng 来定位地图的中心。让我解释一下:我们从服务器获取多边形详细信息,然后将它们传递到编辑模式窗口(Angular UI 引导程序):

forgeGeoTriggerService.GetGeoFence(geotriggerID)
                .then(function (geofenceData) {
                    $scope.modalInstance = $modal.open({
                        windowClass: 'popup-geofence-modal',
                        templateUrl: TemplateUrlProvider.GetUrl('GeofenceModal'),
                        controller: 'EditGeofenceModalController',
                        resolve: {//pass geofenceData from server to geofence obj inside modal
                            geofence: function () {
                                return geofenceData;
                            },
                            triggerID: function () {
                                return geotriggerID
                            }
                        }
                    });
                }, function (error) {
                    $scope.errorMessage = 'There was an error when trying to fetch geofencene details. Please try again later.';
                });
然后在 编辑地理围栏模式控制器 我们

利用从上面的父控制器传递的地理围栏对象

'use strict';
var controllersModule = angular.module('forge.geomanagement.controllers');
controllersModule.controller('EditGeofenceModalController', function ($timeout, $scope, $modalInstance, forgeGeoTriggerService, $rootScope, geofence, triggerID) {
var searchAddressInput: HTMLInputElement;
//make a copy of geofence obj passed into modal
$scope.geofence = {
    FriendlyName: geofence.FriendlyName,
    Coords: angular.copy(geofence.Boundary),
    GeoTags: angular.copy(geofence.GeoTags)
};
$scope.goefenceID = triggerID;
var gCLength = $scope.geofence.Coords.length;
//if first and last coords are the same - remove the last one
if ($scope.geofence.Coords[0].lat === $scope.geofence.Coords[gCLength - 1].lat
    && $scope.geofence.Coords[0].lng === $scope.geofence.Coords[gCLength - 1].lng) {
        $scope.geofence.Coords.pop();
}
//!!!!!!!set the map center to geofence.Center
var geofenceCenter: google.maps.LatLng = new google.maps.LatLng(
    geofence.Center.lat, geofence.Center.lng
    );

注意带有感叹号的评论行。这是我设置地图中心的地方。从服务器返回的地理围栏对象具有中心属性 - 具有纬度和 LNG 属性的 obj。一旦我按照@rayners的建议在测试中的地理围栏模拟对象中将坐标更改为边界,它仍然缺少中心属性。在测试文件中这样设置它解决了问题,我的测试通过了:

geofencemock = {
            FriendlyName: 'mock geofence',
            Boundary: [
                {
                    "lat": 53.5598889724547,
                    "lng": -6.36953830718994
                },
                {
                    "lat": 53.463525599115,
                    "lng": -6.53707981109619
                },
                {
                    "lat": 53.3685818160803,
                    "lng": -6.46841526031494
                },
                {
                    "lat": 53.384966558115,
                    "lng": -5.75430393218994
                },
                {
                    "lat": 53.5598889724547,
                    "lng": -6.34756565093994
                },
                {
                    "lat": 53.5598889724547,
                    "lng": -6.36953830718994
                }
            ],
            GeoTags: ['tag1', 'tag2', 'tag3'],
            Center: {
                "lat": 53.46769593973309,
                "lng": -6.2952017905716735
            }
        }

最新更新