2017-08-11 87 views
0

有以下指令。谷歌地图单元测试

import { Directive, ElementRef, EventEmitter, Output } from '@angular/core'; 
import { NgModel } from '@angular/forms'; 
import {} from 'googlemaps'; 
@Directive({ 
    selector: '[gmap]' 
}) 
export class GmapDirective { 

    @Output() addressFromGoogle: EventEmitter<any> = new EventEmitter(); 
    autocomplete: any; 

    constructor(el: ElementRef) { 
    this.autocomplete = new google.maps.places.Autocomplete(el.nativeElement, { componentRestrictions: { country: "us" } }); 
    google.maps.event.addListener(this.autocomplete, 'place_changed',() => { 
     this.addressFromGoogle.emit(this.autocomplete.getPlace()); 
    }); 
    } 
} 

试图单元测试并拿到google is not defined我如何提供测试床的全局变量?

describe('GmapDirective',() => { 
    let directive: GmapDirective; 
    beforeEach(async(() => { 
    TestBed.configureTestingModule({ 
     imports: [], 
     providers: [ 
     GmapDirective, 
     { provide: ElementRef, useClass: MockElementRef }, 
     { 
      provide: google, useValue: { 
      google: { 
       maps: { 
       Animation: {}, 
       BicyclingLayer: function() { }, 
       Circle: function() { }, 
       ControlPosition: {}, 
       Data: function() { }, 
       DirectionsRenderer: function() { }, 
       DirectionsService: function() { }, 
       DirectionsStatus: {}, 
       DirectionsTravelMode: {}, 
       DirectionsUnitSystem: {}, 
       DistanceMatrixElementStatus: {}, 
       DistanceMatrixService: function() { }, 
       DistanceMatrixStatus: {}, 
       ElevationService: function() { }, 
       ElevationStatus: {}, 
       FusionTablesLayer: function() { }, 
       Geocoder: function() { }, 
       GeocoderLocationType: {}, 
       GeocoderStatus: {}, 
       GroundOverlay: function() { }, 
       ImageMapType: function() { }, 
       InfoWindow: function() { }, 
       KmlLayer: function() { }, 
       KmlLayerStatus: {}, 
       LatLng: function() { }, 
       LatLngBounds: function() { }, 
       MVCArray: function() { }, 
       MVCObject: function() { }, 
       Map: function() { 
        return { 
        setTilt: function() { }, 
        mapTypes: { 
         set: function() { } 
        }, 
        overlayMapTypes: { 
         insertAt: function() { }, 
         removeAt: function() { } 
        } 
        }; 
       }, 
       MapTypeControlStyle: {}, 
       MapTypeId: { 
        HYBRID: '', 
        ROADMAP: '', 
        SATELLITE: '', 
        TERRAIN: '' 
       }, 
       MapTypeRegistry: function() { }, 
       Marker: function() { }, 
       MarkerImage: function() { }, 
       MaxZoomService: function() { 
        return { 
        getMaxZoomAtLatLng: function() { } 
        }; 
       }, 
       MaxZoomStatus: {}, 
       NavigationControlStyle: {}, 
       OverlayView: function() { }, 
       Point: function() { }, 
       Polygon: function() { }, 
       Polyline: function() { }, 
       Rectangle: function() { }, 
       SaveWidget: function() { }, 
       ScaleControlStyle: {}, 
       Size: function() { }, 
       StreetViewCoverageLayer: function() { }, 
       StreetViewPanorama: function() { }, 
       StreetViewService: function() { }, 
       StreetViewStatus: {}, 
       StrokePosition: {}, 
       StyledMapType: function() { }, 
       SymbolPath: {}, 
       TrafficLayer: function() { }, 
       TransitLayer: function() { }, 
       TransitMode: {}, 
       TransitRoutePreference: {}, 
       TravelMode: {}, 
       UnitSystem: {}, 
       ZoomControlStyle: {}, 
       __gjsload__: function() { }, 
       event: { 
        addListener: function() { } 
       }, 
       places: { 
        AutocompleteService: function() { 
        return { 
         getPlacePredictions: function() { } 
        }; 
        } 
       } 
       } 
      } 
      } 
     } 
     ], 
     declarations: [] 
    }).compileComponents(); 
    directive = TestBed.get(GmapDirective); 
    })); 
    it('should create an instance',() => { 
    expect(directive).toBeTruthy(); 
    }); 
}); 

试过上方,这是行不通的,因为谷歌没有注入(预计将在全局命名空间)

回答

0

其中之一是DI是为了解决可测试性是存在的问题。全局可window被嘲笑,但一个更简洁的方法就是给他们提供的供应商:

export const GOOGLE = new InjectionToken('google'); 
export const googleFactory =() => google; 

... 
providers: [{ provide: GOOGLE, useFactory: googleFactory}, ...] 
... 

... 
constructor(el: ElementRef, @Inject(GOOGLE) google) { 
    ... 
} 
... 

然后,它可以在试验台被嘲笑:

... 
providers: [{ provide: GOOGLE, useValue: mockedGoogle }] 
...