javascript – AngularJS Jasmine测试谷歌地图:offsetWidth为null

我只使用Jasmine和Karma(测试运行器)在AngularJS中进行了一些测试

但我现在卡住了.我正在部分视图上集成谷歌地图,我渴望在相应的控制器中测试我为它写的功能(当点击发生时放置标记,改变地图上圆圈的半径,……)

所有功能都有效,但测试似乎要困难得多.这是一个简单的测试,我用它来验证服务是否已定义:

  it('should contain a locationDbService',
    function () {
        expect(locationDbService).toBeDefined();
    });

我在每次测试之前执行了以下代码:

var ctrl, scope, locationDbService;
// inject the $controller and $rootScope services
// in the beforeEach block
beforeEach(inject(function ($controller, $rootScope, _LocationDbService_) {
    // Create a new scope that's a child of the $rootScope
    scope = $rootScope.$new();
    // Create the controller
    ctrl = $controller('AddLocationCtrl', {
        $scope: scope,
        LocationDbService: _LocationDbService_
    });
    locationDbService = _LocationDbService_;
}));

控制器头如下:

.controller('AddLocationCtrl', function ($scope, LocationDbService) {

在控制器中初始化函数:

    var map;

    $scope.initialize = function () {
        var mapOptions = {
            zoom: 15,
            center: new google.maps.LatLng(51.142036, 4.440966)
        };

        map = new google.maps.Map(document.getElementById('map-canvas-add-location'), mapOptions);

    };

    google.maps.event.addDomListener(window, "load", $scope.initialize());

视图:

            <div class="item item-body">
                <div id="map-canvas-add-location"></div>
            </div>

我在开始时遇到的问题是:

我通过将google maps js文件添加到Karma conf文件数组来“修复”它,这是一个正确的解决方案吗?

当我添加js文件并再次运行测试时,我得到以下失败:

我已经在网上搜索了几个小时的解决方案,但找不到它们中的任何一个.我究竟做错了什么?

提前致谢!

最佳答案 对于您的第一个错误屏幕,您是正确的,因为茉莉花测试运行器不包含对google maps js文件的引用.

对于第二个错误,您没有带map-canvas-add-location的div元素.您的视图确实包含div元素,但它没有在您的jasmine测试套件中加载.这是正确的行为,单元测试不应该依赖于特定的dom结构,因为它使它们更脆弱.

我知道有两种方法可以处理第二个错误:

>利用服务将特定的电话打包到谷歌地图
依赖.这就是我目前的角度图项目的工作原理.
>将所有地图级别测试转换为E2E测试而不是单元测试.

我推荐数字1,因为E2E测试不是一个轻松的步骤. E2E测试通常更脆,更难维护.

以下是包装器服务的外观示例:

.factory('GoogleMap', function(){
    return {
        createMap: function(element, options){
            return new google.maps.Map(element, options);
        },
        mapOptions: {
            animation: google.maps.MapTypeId.DROP,
            maxZoom: 15,
            mapTypeControlOptions: {
                position: google.maps.ControlPosition.LEFT_BOTTOM,
                style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
            }
        },
        markerOptions:{
            animation: google.maps.Animation.DROP,
            clickable: true
        },
        position: function(location){
            return new google.maps.LatLng(location.latitude, location.longitude);
        },
        geocode: function(search, successFun){
            var geocoder = new google.maps.Geocoder();
            geocoder.geocode(search, successFun);
        },
        bounds: function(){
            return new google.maps.LatLngBounds();
        }
    };
});

并在代码中使用:

var mapOptions = angular.extend({
        zoom: 15,
        center: GoogleMap.position({latitude: 51.142036, longitude: 4.440966})
    }, GoogleMap.mapOptions);
map = GoogleMap.createMap(document.getElementById('map-canvas-add-location'), mapOptions);

然后在测试中,您需要创建一个模拟的GoogleMap服务,并在该模拟上设置间谍,以断言您的地图是否正确生成.

以下是模拟GoogleMap服务示例:

.factory('mockGoogleMap', function(){
    var mapResult = {
        formatted_address: 'mock formatted address',
        geometry: {
            location: {
                lat: function(){
                    return 1;
                },
                lng: function(){
                    return 2;
                }
            }
        }
    };
    return {
        createMap: function(element, options){
            return {
                //add functions called by your controller on the map here
            };
        },
        mapOptions: {},
        markerOptions: {},
        position: function(location){
            return {latitude: location.latitude, longitude: location.longitude};
        },
        geocode: function(params, success){
            success([mapResult], null);
        },
        geocodeResult: mapResult,
        bounds: function(){
            return {
                extend: function(position){},
                getCenter: function(){ return {}; }
            };
        },
    };
});
点赞