title: How to test an Angular directive using NgZone and Google places?
body: <p>I don't find how to test my angular directive...</p>
  
  <p><strong>google-places.directive.ts</strong></p>
  
  <pre><code>import { Directive, ElementRef, EventEmitter, NgZone, Output } from '@angular/core';
  import {} from '@types/googlemaps';
  
  @Directive({
    selector: '[appGooglePlace]'
  })
  export class AppGooglePlaceDirective {
    @Output() placeChange: EventEmitter&lt;any&gt; = new EventEmitter&lt;any&gt;();
  
    constructor(private el: ElementRef, private ngZone: NgZone) {
      const autocomplete = new google.maps.places.Autocomplete(this.el.nativeElement);
      autocomplete.addListener('place_changed', () =&gt; {
        this.ngZone.run(() =&gt; {
          const place = autocomplete.getPlace();
          this.placeChange.emit(place);
        });
      });
    }
  }
  </code></pre>
  
  <p><strong>mypage.component.html</strong></p>
  
  <pre><code>&lt;input type="search" appGooglePlace (placeChange)="placeChanged($event)"/&gt;
  </code></pre>
  
  <p>It's working fine in the application but not with ng test and i don 't know how to write it... </p>
  
  <p>I have an error : </p>
  
  <blockquote>
    <p>"ReferenceError: google is not defined"</p>
  </blockquote>
  
  <p>And the the following error in dev console :</p>
  
  <blockquote>
    <p>Access to Script at
    '<a href="https://maps.googleapis.com/maps/api/js?key=XXXXX&amp;libraries=places" rel="nofollow noreferrer">https://maps.googleapis.com/maps/api/js?key=XXXXX&amp;libraries=places</a>'
    from origin '<a href="http://localhost:9876" rel="nofollow noreferrer">http://localhost:9876</a>' has been blocked by CORS policy:
    No 'Access-Control-Allow-Origin' header is present on the requested
    resource. Origin '<a href="http://localhost:9876" rel="nofollow noreferrer">http://localhost:9876</a>' is therefore not allowed
    access.</p>
  </blockquote>
  
  <p>The first it's the same behavior if i don't import @types/googlemaps in my directive, but i don't know why in test i get this error. Do i need to define typings somewhere in karma/jasmine ??</p>
  
  <p>And for the second, can my spec.ts can call the real google api ? If i want to test the return of "placeChange" ?</p>
  
  <p>This is my attemp of unit test :</p>
  
  <p><strong>google-places.directive.spec.ts</strong></p>
  
  <pre><code>import { By } from '@angular/platform-browser';
  import { ComponentFixture, TestBed } from '@angular/core/testing';
  import { Component, ElementRef, DebugElement, NgZone } from '@angular/core';
  import { AppGooglePlaceDirective } from './google-place.directive';
  import {} from '@types/googlemaps';
  @Component({
    template: `&lt;input type="search" appGooglePlace (placeChange)="placeChanged($event)" name="test"/&gt;`
  })
  class TestGooglePlaceComponent {}
  
  export class MockElementRef extends ElementRef {}
  export class MockNgZone extends NgZone {
    constructor() {
      super({ enableLongStackTrace: false });
    }
  }
  
  fdescribe('GooglePlaceDirective', () =&gt; {
    let component: TestGooglePlaceComponent;
    let fixture: ComponentFixture&lt;TestGooglePlaceComponent&gt;;
    let zone: NgZone;
    let searchInput: DebugElement;
  
    beforeEach(() =&gt; {
      TestBed.configureTestingModule({
        declarations: [TestGooglePlaceComponent, AppGooglePlaceDirective],
        providers: [{ provide: NgZone, useClass: MockNgZone }]
      });
  
      fixture = TestBed.createComponent(TestGooglePlaceComponent);
      component = fixture.componentInstance;
      searchInput = fixture.debugElement.query(By.css('input[name=test]'));
      zone = new MockNgZone();
    });
  
    it('should create an instance', () =&gt; {
      const directive = new AppGooglePlaceDirective(new MockElementRef(searchInput), zone);
      expect(directive).toBeTruthy();
    });
  });
  </code></pre>
  
  <p>Thanks for your help ! I'm really lost to how to write this unit test...</p>