<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Angular developers: how are you unit testing classes which implement the ArcGIS API for JavaScript? in ArcGIS JavaScript Maps SDK Questions</title>
    <link>https://community.esri.com/t5/arcgis-javascript-maps-sdk-questions/angular-developers-how-are-you-unit-testing/m-p/1006825#M70997</link>
    <description>&lt;P&gt;For what it's worth I came up with a strategy, using the &lt;A href="https://en.wikipedia.org/wiki/Dependency_inversion_principle" target="_blank" rel="noopener"&gt;Dependency Inversion Principle&lt;/A&gt; and the &lt;A href="https://en.wikipedia.org/wiki/Facade_pattern" target="_blank" rel="noopener"&gt;Facade Pattern&lt;/A&gt;, to be able to mock ArcGIS JS API modules and eliminate the HTTP requests being made from &lt;FONT face="courier new,courier"&gt;loadModules()&lt;/FONT&gt;.&lt;/P&gt;&lt;P&gt;I posted in greater detail on my blog here: &lt;A href="https://seesharpdotnet.wordpress.com/2020/12/03/angular-and-arcgis-api-for-javascript-a-unit-testing-strategy-using-dependency-injection-and-the-facade-pattern/" target="_blank" rel="noopener"&gt;https://seesharpdotnet.wordpress.com/2020/12/03/angular-and-arcgis-api-for-javascript-a-unit-testing-strategy-using-dependency-injection-and-the-facade-pattern/&lt;/A&gt;&lt;/P&gt;&lt;P&gt;A working sample application applying this approach and test coverage is available in this repository: &lt;A href="https://github.com/mfcallahan/angular-cli-esri-map-unit-testing" target="_blank" rel="noopener"&gt;https://github.com/mfcallahan/angular-cli-esri-map-unit-testing&lt;/A&gt;&lt;/P&gt;&lt;P&gt;Here is the summary from the repo's &lt;A href="https://github.com/mfcallahan/angular-cli-esri-map-unit-testing/blob/master/README.md" target="_blank" rel="noopener"&gt;README&lt;/A&gt; file:&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;The problem&lt;/STRONG&gt;&lt;BR /&gt;The &lt;A href="https://github.com/Esri/esri-loader" target="_blank" rel="noopener"&gt;esri-loader&lt;/A&gt; allows an application to load Dojo AMD Modules outside of the Dojo Toolkit. A module can be lazy loaded, improving the initial load performance of the application by waiting to fetch API resources until they are actually needed:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="javascript"&gt;// MapService class to encapsulate ArcGIS API
@Injectable({ providedIn: 'root' })
export class MapService {
  mapView?: esri.MapView;

  async initDefaultMap(): Promise&amp;lt;void&amp;gt; {
    // loadModules() will make HTTP requests to arcgis.com to fetch specified modules
    const [Map, MapView] = await loadModules(['esri/Map', 'esri/views/MapView']);

    this.mapView = new MapView({
      map: new Map({ basemap: 'streets' }),
      center: [-112.077, 39.83],
      zoom: 5,
    });
  }
}&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;However, this can make unit testing difficult, as the system under test does not have any reference to the objects in an ArcGIS API module until an HTTP request is made to fetch it. A test for the &lt;FONT face="comic sans ms,sans-serif"&gt;initDefaultMap()&lt;/FONT&gt; method will call &lt;FONT face="courier new,courier"&gt;loadModules()&lt;/FONT&gt; and make HTTP requests to arcgis.com to fetch the resources needed. This may not be desirable for a few reasons:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;The test becomes more like an integration test; we want to assert the &lt;FONT face="courier new,courier"&gt;component.mapView&lt;/FONT&gt; was correctly set inside &lt;FONT face="courier new,courier"&gt;loadModules()&lt;/FONT&gt;, not test that the application could connect to the internet and fetch dependencies.&lt;/LI&gt;&lt;LI&gt;Tests may be executed in an environment which may not have access to the ArcGIS CDN, such as an automated build pipeline or server.&lt;/LI&gt;&lt;LI&gt;Tests to ensure error responses from the request to load an ArcGIS API module (the unhappy path) are handled properly may be necessary.&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="javascript"&gt;// initDefaultMap() unit test
it('should initialize a default map', async () =&amp;gt; {
  await service.initDefaultMap(); // test will make actual HTTP requests!

  expect(service.mapView).not.toBeUndefined();
});&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;My solution&lt;/STRONG&gt;&lt;BR /&gt;Difficult to mock code is difficult to test! By refactoring the application code to follow the&lt;A href="https://en.wikipedia.org/wiki/Dependency_inversion_principle" target="_blank" rel="noopener"&gt; Dependency Inversion Principle&lt;/A&gt; and leverage &lt;A href="https://en.wikipedia.org/wiki/Dependency_injection" target="_blank" rel="noopener"&gt;Dependency Injection&lt;/A&gt;, the tight coupling between the above initDefaultMap() method and the esri-loader can be eliminated. The &lt;A href="https://en.wikipedia.org/wiki/Facade_pattern" target="_blank" rel="noopener"&gt;Facade Pattern&lt;/A&gt; can be used, creating a wrapper class for loadModules() and others methods exported by esri-loader which can then be injected into the class that has a dependencies on ArcGIS API modules. The wrapper class exposes its own loadModules() method which can be easily mocked, eliminating HTTP requests to the ArcGIS CDN in a test suite. A library such as &lt;A href="https://github.com/florinn/typemoq" target="_blank" rel="noopener"&gt;TypeMoq&lt;/A&gt; can be used to create mock instances of the various ArcGIS API modules.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="javascript"&gt;// Singleton service wrapper class for esri-loader
@Injectable({ providedIn: 'root' })
export class EsriLoaderWrapperService {
  constructor() {}

  public async loadModules(modules: string[]): Promise&amp;lt;any[]&amp;gt; {
    return await loadModules(modules);
  }

  public getInstance&amp;lt;T&amp;gt;(type: new (paramObj: any) =&amp;gt; T, paramObj?: any): T {
    return new type(paramObj);
  }
}

// Updated MapService class
@Injectable({ providedIn: 'root' })
export class MapService {
  mapView?: esri.MapView;

  constructor(readonly esriLoaderWrapperService: EsriLoaderWrapperService) {}

  async initDefaultMap(): Promise&amp;lt;void&amp;gt; {
    const [Map, MapView] = await this.esriLoaderWrapperService.loadModules(['esri/Map', 'esri/views/MapView']);

    const map = this.esriLoaderWrapperService.getInstance&amp;lt;esri.Map&amp;gt;(Map, { 'streets' });

    this.mapView = this.esriLoaderWrapperService.getInstance&amp;lt;esri.MapView&amp;gt;(MapView, {
      map,
      center: [-112.077, 39.83],
      zoom: 5,
    });
  }
}

// Updated initDefaultMap() unit test
it('should initialize a default map', async () =&amp;gt; {
  // Arrange
  const mockMap = TypeMoq.Mock.ofType&amp;lt;esri.Map&amp;gt;();
  const mockMapView = TypeMoq.Mock.ofType&amp;lt;esri.MapView&amp;gt;();

  const esriMockTypes = [mockMap, mockMapView];

  const loadModulesSpy = spyOn(service.esriLoaderWrapperService, 'loadModules').and.returnValue(
    Promise.resolve(esriMockTypes)
  );

  const getInstanceSpy = spyOn(service.esriLoaderWrapperService, 'getInstance').and.returnValues(
    ...esriMockTypes.map((mock) =&amp;gt; mock.object)
  );

  // Act
  await service.initDefaultMap(basemap, centerLon, centerLat, zoom, elementRef);

  // Assert
  expect(loadModulesSpy).toHaveBeenCalledTimes(1);
  expect(getInstanceSpy).toHaveBeenCalledTimes(esriMockTypes.length);
  expect(service.mapView).not.toBeUndefined();
  expect(service.mapView).toBe(mockMapView.object);
});&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Fri, 04 Dec 2020 17:01:50 GMT</pubDate>
    <dc:creator>mfcallahan</dc:creator>
    <dc:date>2020-12-04T17:01:50Z</dc:date>
    <item>
      <title>Angular developers: how are you unit testing classes which implement the ArcGIS API for JavaScript?</title>
      <link>https://community.esri.com/t5/arcgis-javascript-maps-sdk-questions/angular-developers-how-are-you-unit-testing/m-p/711637#M66158</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Some more info: I'm building an Angular 7 application using the &lt;A href="https://github.com/Esri/esri-loader" rel="nofollow noopener noreferrer" target="_blank"&gt;esri-loader&lt;/A&gt; 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.&amp;nbsp; &lt;STRONG&gt;Is anyone out there doing this successfully and able to provide some guidance?&amp;nbsp;&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;For example, say I have a MapComponent class that looks like this:&lt;/P&gt;&lt;PRE class="lia-code-sample line-numbers language-none"&gt;&lt;CODE&gt;&lt;SPAN class="keyword token"&gt;export&lt;/SPAN&gt; &lt;SPAN class="keyword token"&gt;class&lt;/SPAN&gt; &lt;SPAN class="token class-name"&gt;MapComponent&lt;/SPAN&gt; &lt;SPAN class="punctuation token"&gt;{&lt;/SPAN&gt;
   mapView&lt;SPAN class="punctuation token"&gt;:&lt;/SPAN&gt; MapView&lt;SPAN class="punctuation token"&gt;;&lt;/SPAN&gt;

   &lt;SPAN class="keyword token"&gt;public&lt;/SPAN&gt; &lt;SPAN class="keyword token"&gt;async&lt;/SPAN&gt; &lt;SPAN class="token function"&gt;initializeMap&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;(&lt;/SPAN&gt;lat&lt;SPAN class="punctuation token"&gt;:&lt;/SPAN&gt; number&lt;SPAN class="punctuation token"&gt;,&lt;/SPAN&gt; lon&lt;SPAN class="punctuation token"&gt;:&lt;/SPAN&gt; number&lt;SPAN class="punctuation token"&gt;,&lt;/SPAN&gt; zoom&lt;SPAN class="punctuation token"&gt;:&lt;/SPAN&gt; number&lt;SPAN class="punctuation token"&gt;)&lt;/SPAN&gt; &lt;SPAN class="punctuation token"&gt;{&lt;/SPAN&gt;
    &lt;SPAN class="keyword token"&gt;const&lt;/SPAN&gt; &lt;SPAN class="punctuation token"&gt;[&lt;/SPAN&gt;Map&lt;SPAN class="punctuation token"&gt;,&lt;/SPAN&gt; MapView&lt;SPAN class="punctuation token"&gt;]&lt;/SPAN&gt; &lt;SPAN class="operator token"&gt;=&lt;/SPAN&gt; &lt;SPAN class="keyword token"&gt;await&lt;/SPAN&gt; &lt;SPAN class="token function"&gt;loadModules&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;(&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;[&lt;/SPAN&gt;&lt;SPAN class="string token"&gt;'esri/Map'&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;,&lt;/SPAN&gt; &lt;SPAN class="string token"&gt;'esri/views/MapView'&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;]&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;)&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;;&lt;/SPAN&gt;

    &lt;SPAN class="keyword token"&gt;this&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;.&lt;/SPAN&gt;mapView &lt;SPAN class="operator token"&gt;=&lt;/SPAN&gt; &lt;SPAN class="keyword token"&gt;new&lt;/SPAN&gt; &lt;SPAN class="token class-name"&gt;MapView&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;(&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;{&lt;/SPAN&gt;
	  zoom&lt;SPAN class="punctuation token"&gt;:&lt;/SPAN&gt; zoom&lt;SPAN class="punctuation token"&gt;,&lt;/SPAN&gt;
	  center&lt;SPAN class="punctuation token"&gt;:&lt;/SPAN&gt; &lt;SPAN class="punctuation token"&gt;[&lt;/SPAN&gt;lat&lt;SPAN class="punctuation token"&gt;,&lt;/SPAN&gt; lon&lt;SPAN class="punctuation token"&gt;]&lt;/SPAN&gt;
      map&lt;SPAN class="punctuation token"&gt;:&lt;/SPAN&gt; &lt;SPAN class="keyword token"&gt;new&lt;/SPAN&gt; &lt;SPAN class="token class-name"&gt;Map&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;(&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;{&lt;/SPAN&gt;
        basemap&lt;SPAN class="punctuation token"&gt;:&lt;/SPAN&gt; &lt;SPAN class="string token"&gt;'streets'&lt;/SPAN&gt;
      &lt;SPAN class="punctuation token"&gt;}&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;)&lt;/SPAN&gt;
    &lt;SPAN class="punctuation token"&gt;}&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;)&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;;&lt;/SPAN&gt;
  &lt;SPAN class="punctuation token"&gt;}&lt;/SPAN&gt;
  
  &lt;SPAN class="keyword token"&gt;public&lt;/SPAN&gt; &lt;SPAN class="keyword token"&gt;async&lt;/SPAN&gt; &lt;SPAN class="token function"&gt;addPointToMap&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;(&lt;/SPAN&gt;lat&lt;SPAN class="punctuation token"&gt;:&lt;/SPAN&gt; number&lt;SPAN class="punctuation token"&gt;,&lt;/SPAN&gt; lon&lt;SPAN class="punctuation token"&gt;:&lt;/SPAN&gt; number&lt;SPAN class="punctuation token"&gt;)&lt;/SPAN&gt; &lt;SPAN class="punctuation token"&gt;{&lt;/SPAN&gt;
    &lt;SPAN class="keyword token"&gt;const&lt;/SPAN&gt; &lt;SPAN class="punctuation token"&gt;[&lt;/SPAN&gt;Graphic&lt;SPAN class="punctuation token"&gt;]&lt;/SPAN&gt; &lt;SPAN class="operator token"&gt;=&lt;/SPAN&gt; &lt;SPAN class="keyword token"&gt;await&lt;/SPAN&gt; &lt;SPAN class="token function"&gt;loadModules&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;(&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;[&lt;/SPAN&gt;&lt;SPAN class="string token"&gt;'esri/Graphic'&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;]&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;)&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;;&lt;/SPAN&gt;
	
	&lt;SPAN class="keyword token"&gt;const&lt;/SPAN&gt; point &lt;SPAN class="operator token"&gt;=&lt;/SPAN&gt; &lt;SPAN class="punctuation token"&gt;{&lt;/SPAN&gt;
	  type&lt;SPAN class="punctuation token"&gt;:&lt;/SPAN&gt; &lt;SPAN class="string token"&gt;"point"&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;,&lt;/SPAN&gt;
	  longitude&lt;SPAN class="punctuation token"&gt;:&lt;/SPAN&gt; lon&lt;SPAN class="punctuation token"&gt;,&lt;/SPAN&gt;
	  latitude&lt;SPAN class="punctuation token"&gt;:&lt;/SPAN&gt; lat
	&lt;SPAN class="punctuation token"&gt;}&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;;&lt;/SPAN&gt;

	&lt;SPAN class="keyword token"&gt;const&lt;/SPAN&gt; markerSymbol &lt;SPAN class="operator token"&gt;=&lt;/SPAN&gt; &lt;SPAN class="punctuation token"&gt;{&lt;/SPAN&gt;
	  type&lt;SPAN class="punctuation token"&gt;:&lt;/SPAN&gt; &lt;SPAN class="string token"&gt;"simple-marker"&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;,&lt;/SPAN&gt;
	  color&lt;SPAN class="punctuation token"&gt;:&lt;/SPAN&gt; &lt;SPAN class="punctuation token"&gt;[&lt;/SPAN&gt;&lt;SPAN class="number token"&gt;226&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;,&lt;/SPAN&gt; &lt;SPAN class="number token"&gt;119&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;,&lt;/SPAN&gt; &lt;SPAN class="number token"&gt;40&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;]&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;,&lt;/SPAN&gt;
	  outline&lt;SPAN class="punctuation token"&gt;:&lt;/SPAN&gt; &lt;SPAN class="punctuation token"&gt;{&lt;/SPAN&gt;
		color&lt;SPAN class="punctuation token"&gt;:&lt;/SPAN&gt; &lt;SPAN class="punctuation token"&gt;[&lt;/SPAN&gt;&lt;SPAN class="number token"&gt;255&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;,&lt;/SPAN&gt; &lt;SPAN class="number token"&gt;255&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;,&lt;/SPAN&gt; &lt;SPAN class="number token"&gt;255&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;]&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;,&lt;/SPAN&gt;
		width&lt;SPAN class="punctuation token"&gt;:&lt;/SPAN&gt; &lt;SPAN class="number token"&gt;2&lt;/SPAN&gt;
	  &lt;SPAN class="punctuation token"&gt;}&lt;/SPAN&gt;
	&lt;SPAN class="punctuation token"&gt;}&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;;&lt;/SPAN&gt;

	&lt;SPAN class="keyword token"&gt;const&lt;/SPAN&gt; pointGraphic &lt;SPAN class="operator token"&gt;=&lt;/SPAN&gt; &lt;SPAN class="keyword token"&gt;new&lt;/SPAN&gt; &lt;SPAN class="token class-name"&gt;Graphic&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;(&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;{&lt;/SPAN&gt;
	  geometry&lt;SPAN class="punctuation token"&gt;:&lt;/SPAN&gt; point&lt;SPAN class="punctuation token"&gt;,&lt;/SPAN&gt;
	  symbol&lt;SPAN class="punctuation token"&gt;:&lt;/SPAN&gt; markerSymbol
	&lt;SPAN class="punctuation token"&gt;}&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;)&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;;&lt;/SPAN&gt;
	
	&lt;SPAN class="keyword token"&gt;this&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;.&lt;/SPAN&gt;mapView&lt;SPAN class="punctuation token"&gt;.&lt;/SPAN&gt;graphics&lt;SPAN class="punctuation token"&gt;.&lt;/SPAN&gt;&lt;SPAN class="token function"&gt;add&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;(&lt;/SPAN&gt;pointGraphic&lt;SPAN class="punctuation token"&gt;)&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;;&lt;/SPAN&gt;
  &lt;SPAN class="punctuation token"&gt;}&lt;/SPAN&gt;
&lt;SPAN class="punctuation token"&gt;}&lt;/SPAN&gt;‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍&lt;SPAN class="line-numbers-rows"&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;I want to test the &lt;SPAN style="font-family: courier new, courier, monospace;"&gt;initializeMap() &lt;/SPAN&gt;and &lt;SPAN style="font-family: courier new, courier, monospace;"&gt;addPointToMap()&lt;/SPAN&gt; 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?&amp;nbsp; A test class might look like this:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;PRE class="lia-code-sample line-numbers language-none"&gt;&lt;CODE&gt;&lt;SPAN class="token function"&gt;describe&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;(&lt;/SPAN&gt;&lt;SPAN class="string token"&gt;'MapComponent'&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;,&lt;/SPAN&gt; &lt;SPAN class="punctuation token"&gt;(&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;)&lt;/SPAN&gt; &lt;SPAN class="operator token"&gt;=&lt;/SPAN&gt;&lt;SPAN class="operator token"&gt;&amp;gt;&lt;/SPAN&gt; &lt;SPAN class="punctuation token"&gt;{&lt;/SPAN&gt;
  &lt;SPAN class="keyword token"&gt;let&lt;/SPAN&gt; fixture&lt;SPAN class="punctuation token"&gt;:&lt;/SPAN&gt; ComponentFixture&lt;SPAN class="operator token"&gt;&amp;lt;&lt;/SPAN&gt;MapComponent&lt;SPAN class="operator token"&gt;&amp;gt;&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;;&lt;/SPAN&gt;
  &lt;SPAN class="keyword token"&gt;let&lt;/SPAN&gt; component&lt;SPAN class="punctuation token"&gt;;&lt;/SPAN&gt;

  &lt;SPAN class="token function"&gt;beforeEach&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;(&lt;/SPAN&gt;&lt;SPAN class="keyword token"&gt;async&lt;/SPAN&gt; &lt;SPAN class="punctuation token"&gt;(&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;)&lt;/SPAN&gt; &lt;SPAN class="operator token"&gt;=&lt;/SPAN&gt;&lt;SPAN class="operator token"&gt;&amp;gt;&lt;/SPAN&gt; &lt;SPAN class="punctuation token"&gt;{&lt;/SPAN&gt;
    TestBed&lt;SPAN class="punctuation token"&gt;.&lt;/SPAN&gt;&lt;SPAN class="token function"&gt;configureTestingModule&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;(&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;{&lt;/SPAN&gt;
      declarations&lt;SPAN class="punctuation token"&gt;:&lt;/SPAN&gt; &lt;SPAN class="punctuation token"&gt;[&lt;/SPAN&gt;MapComponent&lt;SPAN class="punctuation token"&gt;]&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;,&lt;/SPAN&gt;
    &lt;SPAN class="punctuation token"&gt;}&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;)&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;.&lt;/SPAN&gt;&lt;SPAN class="token function"&gt;compileComponents&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;(&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;)&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;;&lt;/SPAN&gt;
	
    fixture &lt;SPAN class="operator token"&gt;=&lt;/SPAN&gt; TestBed&lt;SPAN class="punctuation token"&gt;.&lt;/SPAN&gt;&lt;SPAN class="token function"&gt;createComponent&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;(&lt;/SPAN&gt;MapComponent&lt;SPAN class="punctuation token"&gt;)&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;;&lt;/SPAN&gt;
    component &lt;SPAN class="operator token"&gt;=&lt;/SPAN&gt; fixture&lt;SPAN class="punctuation token"&gt;.&lt;/SPAN&gt;debugElement&lt;SPAN class="punctuation token"&gt;.&lt;/SPAN&gt;componentInstance&lt;SPAN class="punctuation token"&gt;;&lt;/SPAN&gt;
  &lt;SPAN class="punctuation token"&gt;}&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;)&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;;&lt;/SPAN&gt;

  &lt;SPAN class="token function"&gt;it&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;(&lt;/SPAN&gt;&lt;SPAN class="string token"&gt;'should initialize map'&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;,&lt;/SPAN&gt; &lt;SPAN class="keyword token"&gt;async&lt;/SPAN&gt; &lt;SPAN class="punctuation token"&gt;(&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;)&lt;/SPAN&gt; &lt;SPAN class="operator token"&gt;=&lt;/SPAN&gt;&lt;SPAN class="operator token"&gt;&amp;gt;&lt;/SPAN&gt; &lt;SPAN class="punctuation token"&gt;{&lt;/SPAN&gt;
	&lt;SPAN class="comment token"&gt;// calling this function will fetch the ArcGIS JS API dependencies&lt;/SPAN&gt;
    &lt;SPAN class="comment token"&gt;// and create concrete instances of Map and MapView objects - need&lt;/SPAN&gt;
    &lt;SPAN class="comment token"&gt;// to mock these 	&lt;/SPAN&gt;
    &lt;SPAN class="keyword token"&gt;await&lt;/SPAN&gt; component&lt;SPAN class="punctuation token"&gt;.&lt;/SPAN&gt;&lt;SPAN class="token function"&gt;initializeMap&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;(&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;)&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;;&lt;/SPAN&gt;
    &lt;SPAN class="token function"&gt;expect&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;(&lt;/SPAN&gt;component&lt;SPAN class="punctuation token"&gt;.&lt;/SPAN&gt;mapService&lt;SPAN class="punctuation token"&gt;.&lt;/SPAN&gt;mapView&lt;SPAN class="punctuation token"&gt;)&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;.&lt;/SPAN&gt;&lt;SPAN class="token function"&gt;toBeTruthy&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;(&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;)&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;;&lt;/SPAN&gt;
  &lt;SPAN class="punctuation token"&gt;}&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;)&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;;&lt;/SPAN&gt;
  
  &lt;SPAN class="token function"&gt;it&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;(&lt;/SPAN&gt;&lt;SPAN class="string token"&gt;'should add a point to the map'&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;,&lt;/SPAN&gt; &lt;SPAN class="keyword token"&gt;async&lt;/SPAN&gt; &lt;SPAN class="punctuation token"&gt;(&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;)&lt;/SPAN&gt; &lt;SPAN class="operator token"&gt;=&lt;/SPAN&gt;&lt;SPAN class="operator token"&gt;&amp;gt;&lt;/SPAN&gt; &lt;SPAN class="punctuation token"&gt;{&lt;/SPAN&gt;
    &lt;SPAN class="keyword token"&gt;await&lt;/SPAN&gt; component&lt;SPAN class="punctuation token"&gt;.&lt;/SPAN&gt;&lt;SPAN class="token function"&gt;addPointToMap&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;(&lt;/SPAN&gt;&lt;SPAN class="number token"&gt;32.7&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;,&lt;/SPAN&gt; &lt;SPAN class="operator token"&gt;-&lt;/SPAN&gt;&lt;SPAN class="number token"&gt;117.1&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;)&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;;&lt;/SPAN&gt;
    &lt;SPAN class="comment token"&gt;// assert point is created in component.mapService.mapView object&lt;/SPAN&gt;
  &lt;SPAN class="punctuation token"&gt;}&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;)&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;;&lt;/SPAN&gt;
&lt;SPAN class="punctuation token"&gt;}&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;)&lt;/SPAN&gt;&lt;SPAN class="punctuation token"&gt;;&lt;/SPAN&gt;‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍&lt;SPAN class="line-numbers-rows"&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;SPAN&gt;‍&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;As mentioned above, I'm really struggling with how to mock out ArcGIS JS API classes.&amp;nbsp; 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...&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Sun, 12 Dec 2021 06:30:10 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-javascript-maps-sdk-questions/angular-developers-how-are-you-unit-testing/m-p/711637#M66158</guid>
      <dc:creator>mfcallahan</dc:creator>
      <dc:date>2021-12-12T06:30:10Z</dc:date>
    </item>
    <item>
      <title>Re: Angular developers: how are you unit testing classes which implement the ArcGIS API for JavaScript?</title>
      <link>https://community.esri.com/t5/arcgis-javascript-maps-sdk-questions/angular-developers-how-are-you-unit-testing/m-p/711638#M66159</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;If you are concerned about HTTP calls to retrieve modules take&amp;nbsp;a look at using webpack instead of esri-loader. If you can switch over to webpack then all your ArcGIS modules will be in the local bundles. Here's a repo to help get you started in that direction:&amp;nbsp;&lt;A href="https://github.com/Esri/angular-cli-esri-map/tree/arcgis-webpack-angular"&gt;https://github.com/Esri/angular-cli-esri-map/tree/arcgis-webpack-angular&lt;/A&gt;. Unfortunately the spec is broken on that branch, not sure why.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Wed, 09 Oct 2019 18:28:25 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-javascript-maps-sdk-questions/angular-developers-how-are-you-unit-testing/m-p/711638#M66159</guid>
      <dc:creator>AndyGup</dc:creator>
      <dc:date>2019-10-09T18:28:25Z</dc:date>
    </item>
    <item>
      <title>Re: Angular developers: how are you unit testing classes which implement the ArcGIS API for JavaScript?</title>
      <link>https://community.esri.com/t5/arcgis-javascript-maps-sdk-questions/angular-developers-how-are-you-unit-testing/m-p/711639#M66160</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Thanks, this seems like the best way to go about it.&amp;nbsp; I will experiment with the &lt;A href="https://github.com/Esri/arcgis-webpack-plugin"&gt;ArcGIS Webpack plugin&lt;/A&gt; and see if this will allow me to use another library to mock out the API classes.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Wed, 16 Oct 2019 21:23:01 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-javascript-maps-sdk-questions/angular-developers-how-are-you-unit-testing/m-p/711639#M66160</guid>
      <dc:creator>mfcallahan</dc:creator>
      <dc:date>2019-10-16T21:23:01Z</dc:date>
    </item>
    <item>
      <title>Re: Angular developers: how are you unit testing classes which implement the ArcGIS API for JavaScript?</title>
      <link>https://community.esri.com/t5/arcgis-javascript-maps-sdk-questions/angular-developers-how-are-you-unit-testing/m-p/711640#M66161</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Is there any specific&amp;nbsp;technical difficulty, so that&amp;nbsp;we are not supporting&amp;nbsp; Unit test cases for the esri-loader?&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Wed, 07 Oct 2020 10:27:34 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-javascript-maps-sdk-questions/angular-developers-how-are-you-unit-testing/m-p/711640#M66161</guid>
      <dc:creator>PanditSargar</dc:creator>
      <dc:date>2020-10-07T10:27:34Z</dc:date>
    </item>
    <item>
      <title>Re: Angular developers: how are you unit testing classes which implement the ArcGIS API for JavaScript?</title>
      <link>https://community.esri.com/t5/arcgis-javascript-maps-sdk-questions/angular-developers-how-are-you-unit-testing/m-p/1006825#M70997</link>
      <description>&lt;P&gt;For what it's worth I came up with a strategy, using the &lt;A href="https://en.wikipedia.org/wiki/Dependency_inversion_principle" target="_blank" rel="noopener"&gt;Dependency Inversion Principle&lt;/A&gt; and the &lt;A href="https://en.wikipedia.org/wiki/Facade_pattern" target="_blank" rel="noopener"&gt;Facade Pattern&lt;/A&gt;, to be able to mock ArcGIS JS API modules and eliminate the HTTP requests being made from &lt;FONT face="courier new,courier"&gt;loadModules()&lt;/FONT&gt;.&lt;/P&gt;&lt;P&gt;I posted in greater detail on my blog here: &lt;A href="https://seesharpdotnet.wordpress.com/2020/12/03/angular-and-arcgis-api-for-javascript-a-unit-testing-strategy-using-dependency-injection-and-the-facade-pattern/" target="_blank" rel="noopener"&gt;https://seesharpdotnet.wordpress.com/2020/12/03/angular-and-arcgis-api-for-javascript-a-unit-testing-strategy-using-dependency-injection-and-the-facade-pattern/&lt;/A&gt;&lt;/P&gt;&lt;P&gt;A working sample application applying this approach and test coverage is available in this repository: &lt;A href="https://github.com/mfcallahan/angular-cli-esri-map-unit-testing" target="_blank" rel="noopener"&gt;https://github.com/mfcallahan/angular-cli-esri-map-unit-testing&lt;/A&gt;&lt;/P&gt;&lt;P&gt;Here is the summary from the repo's &lt;A href="https://github.com/mfcallahan/angular-cli-esri-map-unit-testing/blob/master/README.md" target="_blank" rel="noopener"&gt;README&lt;/A&gt; file:&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;The problem&lt;/STRONG&gt;&lt;BR /&gt;The &lt;A href="https://github.com/Esri/esri-loader" target="_blank" rel="noopener"&gt;esri-loader&lt;/A&gt; allows an application to load Dojo AMD Modules outside of the Dojo Toolkit. A module can be lazy loaded, improving the initial load performance of the application by waiting to fetch API resources until they are actually needed:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="javascript"&gt;// MapService class to encapsulate ArcGIS API
@Injectable({ providedIn: 'root' })
export class MapService {
  mapView?: esri.MapView;

  async initDefaultMap(): Promise&amp;lt;void&amp;gt; {
    // loadModules() will make HTTP requests to arcgis.com to fetch specified modules
    const [Map, MapView] = await loadModules(['esri/Map', 'esri/views/MapView']);

    this.mapView = new MapView({
      map: new Map({ basemap: 'streets' }),
      center: [-112.077, 39.83],
      zoom: 5,
    });
  }
}&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;However, this can make unit testing difficult, as the system under test does not have any reference to the objects in an ArcGIS API module until an HTTP request is made to fetch it. A test for the &lt;FONT face="comic sans ms,sans-serif"&gt;initDefaultMap()&lt;/FONT&gt; method will call &lt;FONT face="courier new,courier"&gt;loadModules()&lt;/FONT&gt; and make HTTP requests to arcgis.com to fetch the resources needed. This may not be desirable for a few reasons:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;The test becomes more like an integration test; we want to assert the &lt;FONT face="courier new,courier"&gt;component.mapView&lt;/FONT&gt; was correctly set inside &lt;FONT face="courier new,courier"&gt;loadModules()&lt;/FONT&gt;, not test that the application could connect to the internet and fetch dependencies.&lt;/LI&gt;&lt;LI&gt;Tests may be executed in an environment which may not have access to the ArcGIS CDN, such as an automated build pipeline or server.&lt;/LI&gt;&lt;LI&gt;Tests to ensure error responses from the request to load an ArcGIS API module (the unhappy path) are handled properly may be necessary.&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="javascript"&gt;// initDefaultMap() unit test
it('should initialize a default map', async () =&amp;gt; {
  await service.initDefaultMap(); // test will make actual HTTP requests!

  expect(service.mapView).not.toBeUndefined();
});&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;My solution&lt;/STRONG&gt;&lt;BR /&gt;Difficult to mock code is difficult to test! By refactoring the application code to follow the&lt;A href="https://en.wikipedia.org/wiki/Dependency_inversion_principle" target="_blank" rel="noopener"&gt; Dependency Inversion Principle&lt;/A&gt; and leverage &lt;A href="https://en.wikipedia.org/wiki/Dependency_injection" target="_blank" rel="noopener"&gt;Dependency Injection&lt;/A&gt;, the tight coupling between the above initDefaultMap() method and the esri-loader can be eliminated. The &lt;A href="https://en.wikipedia.org/wiki/Facade_pattern" target="_blank" rel="noopener"&gt;Facade Pattern&lt;/A&gt; can be used, creating a wrapper class for loadModules() and others methods exported by esri-loader which can then be injected into the class that has a dependencies on ArcGIS API modules. The wrapper class exposes its own loadModules() method which can be easily mocked, eliminating HTTP requests to the ArcGIS CDN in a test suite. A library such as &lt;A href="https://github.com/florinn/typemoq" target="_blank" rel="noopener"&gt;TypeMoq&lt;/A&gt; can be used to create mock instances of the various ArcGIS API modules.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="javascript"&gt;// Singleton service wrapper class for esri-loader
@Injectable({ providedIn: 'root' })
export class EsriLoaderWrapperService {
  constructor() {}

  public async loadModules(modules: string[]): Promise&amp;lt;any[]&amp;gt; {
    return await loadModules(modules);
  }

  public getInstance&amp;lt;T&amp;gt;(type: new (paramObj: any) =&amp;gt; T, paramObj?: any): T {
    return new type(paramObj);
  }
}

// Updated MapService class
@Injectable({ providedIn: 'root' })
export class MapService {
  mapView?: esri.MapView;

  constructor(readonly esriLoaderWrapperService: EsriLoaderWrapperService) {}

  async initDefaultMap(): Promise&amp;lt;void&amp;gt; {
    const [Map, MapView] = await this.esriLoaderWrapperService.loadModules(['esri/Map', 'esri/views/MapView']);

    const map = this.esriLoaderWrapperService.getInstance&amp;lt;esri.Map&amp;gt;(Map, { 'streets' });

    this.mapView = this.esriLoaderWrapperService.getInstance&amp;lt;esri.MapView&amp;gt;(MapView, {
      map,
      center: [-112.077, 39.83],
      zoom: 5,
    });
  }
}

// Updated initDefaultMap() unit test
it('should initialize a default map', async () =&amp;gt; {
  // Arrange
  const mockMap = TypeMoq.Mock.ofType&amp;lt;esri.Map&amp;gt;();
  const mockMapView = TypeMoq.Mock.ofType&amp;lt;esri.MapView&amp;gt;();

  const esriMockTypes = [mockMap, mockMapView];

  const loadModulesSpy = spyOn(service.esriLoaderWrapperService, 'loadModules').and.returnValue(
    Promise.resolve(esriMockTypes)
  );

  const getInstanceSpy = spyOn(service.esriLoaderWrapperService, 'getInstance').and.returnValues(
    ...esriMockTypes.map((mock) =&amp;gt; mock.object)
  );

  // Act
  await service.initDefaultMap(basemap, centerLon, centerLat, zoom, elementRef);

  // Assert
  expect(loadModulesSpy).toHaveBeenCalledTimes(1);
  expect(getInstanceSpy).toHaveBeenCalledTimes(esriMockTypes.length);
  expect(service.mapView).not.toBeUndefined();
  expect(service.mapView).toBe(mockMapView.object);
});&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 04 Dec 2020 17:01:50 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-javascript-maps-sdk-questions/angular-developers-how-are-you-unit-testing/m-p/1006825#M70997</guid>
      <dc:creator>mfcallahan</dc:creator>
      <dc:date>2020-12-04T17:01:50Z</dc:date>
    </item>
    <item>
      <title>Re: Angular developers: how are you unit testing classes which implement the ArcGIS API for JavaScript?</title>
      <link>https://community.esri.com/t5/arcgis-javascript-maps-sdk-questions/angular-developers-how-are-you-unit-testing/m-p/1030414#M71859</link>
      <description>&lt;P&gt;I had to pop by and say THANK YOU for this. It's so well documented and explained.&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 25 Feb 2021 13:44:31 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-javascript-maps-sdk-questions/angular-developers-how-are-you-unit-testing/m-p/1030414#M71859</guid>
      <dc:creator>rogenjh</dc:creator>
      <dc:date>2021-02-25T13:44:31Z</dc:date>
    </item>
  </channel>
</rss>

