"Async function did not complete within 5000ms" when creating a unit test on a page with AGM

10.7k views Asked by At

I just created a component with a map for my ionic+angular app.

It's quite simple, just display one marker at one location:

<ion-header>
  <ion-toolbar color="primary">
    <ion-title>Spots</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>
  <agm-map [latitude]="lat" [longitude]="lng">
    <agm-marker [latitude]="lat" [longitude]="lng"></agm-marker>
  </agm-map>
</ion-content>

And the TS file:

import { Component, OnInit } from '@angular/core';

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

  lat = 51.678418;
  lng = 7.809007;
  constructor() { }

  ngOnInit() {
  }

}

it works, I get my map displayed. For the test I had to additionally install @types/googlemaps:

npm install --save-dev @types/googlemaps

but now my test gives me this error:

Error: Timeout - Async function did not complete within 5000ms (set by jasmine.DEFAULT_TIMEOUT_INTERVAL)

My test is the default one of ionic(just added AGM module):

import { AgmCoreModule } from '@agm/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';

import { MapPage } from './map.page';

describe('MapPage', () => {
  let component: MapPage;
  let fixture: ComponentFixture<MapPage>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [MapPage],
      imports: [
        IonicModule.forRoot(),
        AgmCoreModule.forRoot({
          apiKey: 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
        }),
      ],
    }).compileComponents();

    fixture = TestBed.createComponent(MapPage);
    component = fixture.componentInstance;
    fixture.detectChanges();
  }));

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

Any idea what is going on? I've not much information in the error and I'm a bit lost what async function may not have completed and what could be wrong? Is it the test? Or the code?

Edit If I just increment the timeout like specified here, it works, but I don't understand what would take 5 seconds to complete?

I am getting Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL Error

2

There are 2 answers

7
AliF50 On

I am thinking it is stuck on the first beforeEach on the compileComponents. Maybe it doesn't like the configuration.

Add these logs to confirm the suspicion:

beforeEach(async(() => {
    console.log('In Before Each');
    TestBed.configureTestingModule({
      declarations: [MapPage],
      imports: [
        IonicModule.forRoot(),
        AgmCoreModule.forRoot({
          apiKey: 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
        }),
      ],
    }).compileComponents();
    console.log('In after compile components');
    fixture = TestBed.createComponent(MapPage);
    component = fixture.componentInstance;
    fixture.detectChanges();
    console.log('After calling fixture.detectChanges');
  }));

I am thinking you won't see In after compile components and I don't think you need IonicModule.forRoot(). https://www.joshmorony.com/introduction-to-testing-ionic-2-applications-with-testbed/

If you don't see In after compile components, something is wrong with your imports or configuration.

Try this:

import { NO_ERRORS_SCHEMA } from '@angular/core';
....
beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [MapPage],
      schemas: [NO_ERRORS_SCHEMA], // NO_ERRORS_SCHEMA basically says if you don't 
                                  // understand HTML markup, ignore it.
    }).compileComponents();

    fixture = TestBed.createComponent(MapPage);
    component = fixture.componentInstance;
    fixture.detectChanges();
  }));
0
Evgeny Cheryomushkin On

If you want to use async function in tests, then you should also use async in your it clause:

  it('should create', async () => {
    expect(component).toBeTruthy();
  });

or use done()

  it('should create', (done) => {
    expect(component).toBeTruthy();
    done();
  });

Hope this help