AnsweredAssumed Answered

Angular developers: how are you unit testing classes which implement the ArcGIS API for JavaScript?

Question asked by c_sharp_dotnet on Oct 8, 2019
Latest reply on Oct 16, 2019 by c_sharp_dotnet

Some more info: I'm building an Angular 7 application using the esri-loader and I'm really struggling with trying figure out the best way to mock ArcGIS JS API dependencies in my tests. I have come across very little sample code for applications built with frameworks other than dojo that use the ArcGIS JS API and also contain meaningful unit tests.  Is anyone out there doing this successfully and able to provide some guidance? 

 

For example, say I have a MapComponent class that looks like this:

export class MapComponent {
   mapView: MapView;

   public async initializeMap(lat: number, lon: number, zoom: number) {
    const [Map, MapView] = await loadModules(['esri/Map', 'esri/views/MapView']);

    this.mapView = new MapView({
       zoom: zoom,
       center: [lat, lon]
      map: new Map({
        basemap: 'streets'
      })
    });
  }
 
  public async addPointToMap(lat: number, lon: number) {
    const [Graphic] = await loadModules(['esri/Graphic']);
     
     const point = {
       type: "point",
       longitude: lon,
       latitude: lat
     };

     const markerSymbol = {
       type: "simple-marker",
       color: [226, 119, 40],
       outline: {
          color: [255, 255, 255],
          width: 2
       }
     };

     const pointGraphic = new Graphic({
       geometry: point,
       symbol: markerSymbol
     });
     
     this.mapView.graphics.add(pointGraphic);
  }
}

I want to test the initializeMap() and addPointToMap() functions, but what is the best way to do this without actually making an http request to get the required API modules and creating concrete instances of each class I need?  A test class might look like this:

 

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

  beforeEach(async () => {
    TestBed.configureTestingModule({
      declarations: [MapComponent],
    }).compileComponents();
     
    fixture = TestBed.createComponent(MapComponent);
    component = fixture.debugElement.componentInstance;
  });

  it('should initialize map', async () => {
     // calling this function will fetch the ArcGIS JS API dependencies
    // and create concrete instances of Map and MapView objects - need
    // to mock these      
    await component.initializeMap();
    expect(component.mapService.mapView).toBeTruthy();
  });
 
  it('should add a point to the map', async () => {
    await component.addPointToMap(32.7, -117.1);
    // assert point is created in component.mapService.mapView object
  });
});

 

As mentioned above, I'm really struggling with how to mock out ArcGIS JS API classes.  When testing my own code, I would implement a class from some interface and use DI to assist with testing, but I'm not seeing how I can test the ArcGIS API classes. Help me interwebs, you're my only hope...

Outcomes