1

I updated an Angular project (8 -> 11) and the dependencies. Previously the project used the the @agm/core (https://github.com/SebastianM/angular-google-maps) package, which is not compatible with Angular 11. So I replaced it and followed the suggestions to use the @angular/google-maps directly. Not a big deal, everything working as expected except the tests.

The map is part of an component and the Google API ist loaded there (with prevention of loading it multiple times):

import { Component, OnInit, ViewChild } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { environment } from 'src/environments/environment';
import { GoogleMap } from '@angular/google-maps';

@Component({
  selector: 'app-map',
  templateUrl: './map.component.html',
  styleUrls: ['./map.component.scss']
})
export class MapComponent implements OnInit {

  @ViewChild(GoogleMap, { static: false }) map: GoogleMap;

  apiLoaded: Observable<boolean>;

  constructor(httpClient: HttpClient) {
    if (window.google === undefined) {
      this.apiLoaded = httpClient.jsonp(`https://maps.googleapis.com/maps/api/js?key=${environment.googleAPIKey}`, 'callback')
          .pipe(
            // Doing preparation stuff
          );
    }
    else {
      this.apiLoaded = of(true);
    }
  }

}

Running ng serve everything is working as expected. But as there are already a lot of tests I ran into problems running ng test:

Unhandled promise rejection: InvalidValueError: ng_jsonp_callback_0 is not a function
error properties: null({ constructor: Function })
Error: 
    at new ge (https://maps.googleapis.com/maps/api/js?key=<api-key>&callback=ng_jsonp_callback_0:70:72)
    at Object._.he (https://maps.googleapis.com/maps/api/js?key=<api-key>&callback=ng_jsonp_callback_0:70:182)
    at Nj (https://maps.googleapis.com/maps/api/js?key=<api-key>&callback=ng_jsonp_callback_0:146:233)
    at https://maps.googleapis.com/maps/api/js?key=<api-key>&callback=ng_jsonp_callback_0:146:118
    at ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-evergreen.js:364:1)
    at Zone.run (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-evergreen.js:123:1)
    at http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-evergreen.js:857:1
    at ZoneDelegate.invokeTask (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-evergreen.js:399:1)
    at Zone.runTask (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-evergreen.js:167:1)
    at drainMicroTaskQueue (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-evergreen.js:569:1)

So I guess the Google API is not present during the test. I tried the following things already without any success:

  • adding the Google API loading in the index.html:
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"></script>
  • adding the Link to the Karma config file in files section:
    files: [
      'https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY'
    ],
  • downloading the links content, putting it into a file and adding the referenced file in the Karma config in files section. This works for a few times but also throws errors soon ant hus is not a solution for automated testing on Jenkins.
  • trying one of the mocks online. The existing tests seem to use a lot of functions there so testing with a mocked API also fails.
  • trying to load the API in the test file before running the tests but also not working as expected:
  beforeEach(waitForAsync(() => {
    httpClient.jsonp(`https://maps.googleapis.com/maps/api/js?key=${environment.googleAPIKey}`, 'callback');

I still want to try to move the API loading into a service, but I think this does not change anything. Also downloading the API pre test to load it in the Karma config does not seem to be a good solution either.

How can I ensure to have the current Google Maps API present for testing in an elegant manner?

1 Answer 1

2

I fixed it for now with a pretest script:

package.json:

//...
  "scripts": {
    //...
    "pretest": "./pretest.sh",
    "test": "ng test",
//...

The script loads the API code before testing (pretest.sh):

echo "Running 'pretest.sh' script do download Google Maps API for testing..."
rm google-maps-api.js
date +"// Download time: %Y-%m-%d %H:%M" >> google-maps-api.js
curl 'https://maps.googleapis.com/maps/api/js?key=<API_KEY>' >> google-maps-api.js
echo "'pretest.sh' finished"

And Karma loads the file for testing in the karma.config.js files section:

module.exports = function (config) {
  config.set({
    basePath: '',
    plugins: [
      //...
    ],
    files: [
      'google-maps-api.js'
    ],
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.