2016-11-28 56 views
0

我已經創建了一個Angular2應用程序(+ Webpack)。我添加了一個顯示Openlayers3地圖的組件。它還添加了一些標記和一個多邊形。我對功能感到滿意,但爲它寫測試幾乎證明是不可能的。Angular2 + Openlayers3:地圖渲染時測試失敗。寫作考試不可能?

這是測試的源代碼(我還沒有添加任何期望陳述尚未測試似乎時的OpenLayers試圖呈現地圖打破

/* 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 

    }); 
}); 

我所有的努力,至今只生產了這個。錯誤信息運行測試時(請參見下面的源代碼(S)

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) 

OK,這裏是所涉及的文件的源代碼:我開始與服務提供Openlayers3到組件

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


@Injectable() 
export class OlService { 

    get(): any { 
     return ol; 
    } 
} 

前進到組件。 (我刪除了層URL)的

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

} 

回答

1

根據給定的錯誤堆棧,檢查在ol.js相關的源代碼,這可以解釋發生了什麼對我來說:

第一個錯誤行:

在的Kc(的WebPack:///~/openlayers/dist/ol.js:43:372 < - 果報shim.js:70246:398)

釷在ol.jsË片段:43:372:

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

第二誤差線:

在Object.fromLonLat(的WebPack:///~/openlayers/dist/ol.js:768 :188 < - 果報shim.js:70971:196)

在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」,這是一個投影。你能否在創建地圖之前檢查是否設置了正確的投影?