Angular2 + Openlayers3:地图渲染时测试失败.编写测试不可能吗? [英] Angular2 + Openlayers3: Test fails when map renders. Writing tests impossible?

查看:113
本文介绍了Angular2 + Openlayers3:地图渲染时测试失败.编写测试不可能吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经创建了一个Angular2应用程序(+ Webpack).我添加了一个显示Openlayers3贴图的组件,还添加了一些标记和一个多边形.我对该功能感到满意,但是事实证明,为它编写测试几乎是不可能的.

I have create an Angular2 app (+Webpack). I added a component which shows an Openlayers3 map.It also adds a few markers and a polygon. I am reasonable happy with the functionality, but writing a test for it nearly proves impossible.

这是测试源代码:(我还没有添加任何Expect语句.当Openlayers尝试渲染地图时,该测试似乎中断了.

This is the test source code: ( I have not added any expect statements yet. The test seems to break when Openlayers tries to render the map.

/* tslint:disable:no-unused-variable */
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {DebugElement, NO_ERRORS_SCHEMA} from '@angular/core';
import * as ol from 'openlayers';


import {OlComponent} from './ol.component';

let comp: OlComponent;

describe('OlComponent', () => {

    let fixture: ComponentFixture<OlComponent>;
    let component: OlComponent;


    let element: any;

    beforeEach(async(() => {
        TestBed.configureTestingModule({
            declarations: [
                OlComponent
            ],
            schemas: [NO_ERRORS_SCHEMA],

        })

    }))


    it('should display the map', () => {
        TestBed.overrideComponent(OlComponent, {
            set: {
                template: '<div id="map" style="width:10px;height:10px"></div>'
            }
        });
        fixture = TestBed.createComponent(OlComponent);
        console.log(fixture);
        component = fixture.componentInstance;


        element = fixture.nativeElement;
        console.log(element);
        let map = element.querySelector('#map');
        map.style.width = "100px";
        map.style.height = "100px";

        component.ngOnInit();
        fixture.detectChanges

    });
});

到目前为止,我所有的努力仅在运行测试时才产生此错误消息(请参见下面的源代码.

All my efforts so far have only produced this error message when running the test (see source code(s) below.

OlComponent
✖ should display the map
  Chrome 53.0.2785 (Linux 0.0.0)
TypeError: Cannot read property 'length' of undefined
    at Kc (webpack:///~/openlayers/dist/ol.js:43:372 <- karma-shim.js:70246:398)
    at Object.fromLonLat (webpack:///~/openlayers/dist/ol.js:768:188 <- karma-shim.js:70971:196)
    at OlComponent.createMap (webpack:///src/app/ol-maps/ol.component.ts:9:1914 <- karma-shim.js:70159:1929)
    at OlComponent.ngOnInit (webpack:///src/app/ol-maps/ol.component.ts:9:6364 <- karma-shim.js:70159:6369)
    at Object.<anonymous> (webpack:///src/app/ol-maps/ol.component.spec.ts:33:0 <- karma-shim.js:53653:19)
    at ZoneDelegate.invoke (webpack:///~/zone.js/dist/zone.js:232:0 <- karma-shim.js:40990:26)
    at ProxyZoneSpec.onInvoke (webpack:///~/zone.js/dist/proxy.js:79:0 <- karma-shim.js:40654:39)
    at ZoneDelegate.invoke (webpack:///~/zone.js/dist/zone.js:231:0 <- karma-shim.js:40989:32)
    at Zone.run (webpack:///~/zone.js/dist/zone.js:114:0 <- karma-shim.js:40872:43)
    at Object.<anonymous> (webpack:///~/zone.js/dist/jasmine-patch.js:102:0 <- karma-shim.js:40369:34)
    at webpack:///~/@angular/core/bundles/core-testing.umd.js:91:0 <- karma-shim.js:3519:21
    at ZoneDelegate.invoke (webpack:///~/zone.js/dist/zone.js:232:0 <- karma-shim.js:40990:26)
    at AsyncTestZoneSpec.onInvoke (webpack:///~/zone.js/dist/async-test.js:49:0 <- karma-shim.js:39959:39)
    at ProxyZoneSpec.onInvoke (webpack:///~/zone.js/dist/proxy.js:76:0 <- karma-shim.js:40651:39)
    at ZoneDelegate.invoke (webpack:///~/zone.js/dist/zone.js:231:0 <- karma-shim.js:40989:32)
    at Zone.run (webpack:///~/zone.js/dist/zone.js:114:0 <- karma-shim.js:40872:43)
    at AsyncTestZoneSpec._finishCallback (webpack:///~/@angular/core/bundles/core-testing.umd.js:86:0 <- karma-shim.js:3514:29)
    at webpack:///~/zone.js/dist/async-test.js:38:0 <- karma-shim.js:39948:31
    at ZoneDelegate.invokeTask (webpack:///~/zone.js/dist/zone.js:265:0 <- karma-shim.js:41023:35)
    at Zone.runTask (webpack:///~/zone.js/dist/zone.js:154:0 <- karma-shim.js:40912:47)
    at ZoneTask.invoke (webpack:///~/zone.js/dist/zone.js:335:0 <- karma-shim.js:41093:33)
    at data.args.(anonymous function) (webpack:///~/zone.js/dist/zone.js:970:0 <- karma-shim.js:41728:25)

好的,这是所涉及文件的源代码:我首先从向组件提供Openlayers3的服务开始

OK, here is the source code of the files involved: I am starting of with a service providing Openlayers3 to the component

import {Injectable} from '@angular/core';
import * as ol from 'openlayers';


@Injectable()
export class OlService {

    get(): any {
        return ol;
    }
}

继续该组件. (我删除了图层网址)

Moving on to the component. (I removed the layers URLs)

import {Component, OnInit, Input} from '@angular/core';
import {OlService} from './ol.service';

@Component({
    selector: 'my-map',
    templateUrl: './ol.component.html',
    styleUrls: ['./ol.component.scss'],
    providers: [OlService]
})
export class OlComponent implements OnInit {

    @Input() lnglat: [number, number];
    @Input() zoom: number;

    private map;
    public layers = [];
    private vectorSource;

    constructor(private olService: OlService) {

    }

    createMap = () => {
        let ol = this.olService.get();
        this.vectorSource = new ol.source.Vector({});
        // define layers

        let OSM = new ol.layer.Tile({
            source: new ol.source.OSM()
        });
        OSM.set('name', 'Openstreetmap');


        let geography = new ol.layer.Tile({
            source: new ol.source.TileJSON({
                url: '',
                crossOrigin: '',
            }),
            visible: false
        });
        geography.set('name', 'Geography');

        let boundaries = new ol.layer.Tile({
            opacity: 0.5,

            source: new ol.source.TileWMS({
                url: '',
                params: {
                    'LAYERS': 'fwsys:fwsys_region',
                    'TILED': true,
                    'transparent': 'true',
                    'format': 'image/png'
                },
                serverType: 'geoserver',
                projection: ol.proj.get('EPSG:3857')
            })
        });
        boundaries.set('name', 'Boundaries');
        let vector = new ol.layer.Vector({
            source: this.vectorSource
        });

        this.map = new ol.Map({
            target: 'map',
            layers: [OSM, geography, vector, boundaries],
            view: new ol.View({
                center: ol.proj.fromLonLat(this.lnglat),
                zoom: this.zoom,
                projection: ol.proj.get('EPSG:3857')
            })
        });

        let select_interaction = new ol.interaction.Select();

        this.map.addInteraction(select_interaction);

        // add popup for all features
        let container = document.getElementById('popup');
        let content = document.getElementById('popup-content');
        let closer = document.getElementById('popup-closer');


        let popup = new ol.Overlay({
            element: container,
            autoPan: true,
            positioning: 'bottom-center',
            stopEvent: false,
            offset: [0, -5]
        });

        closer.onclick = function () {
            popup.setPosition(undefined);
            closer.blur();
            return false;
        };
        this.map.addOverlay(popup);

        this.map.on('click', (evt) => {
            let feature = this.map.forEachFeatureAtPixel(evt.pixel, (feat) => {
                return feat;
            });
            if (feature) {
                let coordinate = evt.coordinate;
                content.innerHTML = feature.get('name');
                popup.setPosition(coordinate);
            }


        });
        this.addLayerSwitcher([OSM, geography, boundaries]);
        this.addMarker([174.76, -37.10], 'Close to Auckland', 'akl1');
        this.addMarker([173.76, -37.10], 'Out in in waters', 'pacific1');

        this.addPolygon([[174.76, -37.18], [176.76, -37.18], [176.76, -38.18], [174.76, -38.18]], 'Hamilton', 'id_hamilton');
    };

    addPolygon = (polygon: [[number, number]], name: string, id: string) => {
        let ol = this.olService.get();
        let projectedPolygon = [];

        for (let poly of polygon) {
            projectedPolygon.push(ol.proj.transform(poly, 'EPSG:4326', 'EPSG:3857'));
        }

        let p = new ol.geom.Polygon([projectedPolygon]);

        let featurething = new ol.Feature({
            name: name,
            id: id,
            geometry: p
        });

        this.vectorSource.addFeature(featurething);

    };

    addMarker = (coords: [number, number], name: string, id: string) => {
        let ol = this.olService.get();
        let iconFeature = new ol.Feature({
            geometry: new ol.geom.Point(ol.proj.transform(coords, 'EPSG:4326', 'EPSG:3857')),
            name: name,
            id: id,
        });

        let iconStyle = new ol.style.Style({
            image: new ol.style.Icon(/** @type {olx.style.IconOptions} */ ({
                opacity: 0.75,
                anchor: [0.5, 1],
                src: '//cdn4.iconfinder.com/data/icons/pictype-free-vector-icons/16/location-alt-32.png'
            }))
        });

        iconFeature.setStyle(iconStyle);

        this.vectorSource.addFeature(iconFeature);

    }

    addLayerSwitcher = (layers: [any]) => {

        this.layers = layers;

    }
    toggleLayer = (layer, evt) => {
        evt.target.blur();
        if (layer.getVisible()) {
            layer.setVisible(false);

        } else {
            layer.setVisible(true);
        }

    }

    ngOnInit() {
        this.createMap();
    }

}

推荐答案

根据给定的错误堆栈,检查ol.js中的相关源代码,这说明了发生了什么事情:

According to the given error stack, checked the related source code in ol.js, which explains what's happened for me:

第一个错误行:

at Kc(webpack:///~/openlayers/dist/ol.js:43:372<- karma-shim.js:70246:398)

at Kc (webpack:///~/openlayers/dist/ol.js:43:372 <- karma-shim.js:70246:398)

ol.js:43:372中的代码段:

The snippet at ol.js:43:372:

function Kc(a,b,c){return Ic(b,c)(a,void 0,a.length)}

第二行错误:

at Object.fromLonLat(webpack:///~/openlayers/dist/ol.js:768:188<- karma-shim.js:70971:196)

at Object.fromLonLat (webpack:///~/openlayers/dist/ol.js:768:188 <- karma-shim.js:70971:196)

ol.js:768:188上的代码段

The snippet at ol.js:768:188

r("ol.proj.fromLonLat",function(a,b){return Kc(a,"EPSG:4326",void 0!==b?b:"EPSG:3857")});

我想调用函数Kc(a,b,c)遗漏了参数"a",它是一个投影.您可以在创建地图之前检查是否设置了正确的投影吗?

I suppose the invoking function Kc(a,b,c) missed parameter "a", which is a projection. Could you check if you have set the right projection before creating the map?

这篇关于Angular2 + Openlayers3:地图渲染时测试失败.编写测试不可能吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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