# Testing Cesium in Jest

**URL:** <https://community.cesium.com/t/testing-cesium-in-jest/20977>\
**Category:** CesiumJS\
**Created:** [October 27, 2022, 5:52pm UTC](https://community.cesium.com/t/testing-cesium-in-jest/20977 "2022-10-27T17:52:09Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![sebheron](https://sea2.discourse-cdn.com/cesium/user_avatar/community.cesium.com/sebheron/32/10801_2.png) [@sebheron](https://community.cesium.com/u/sebheron)\
**Post date:** [October 27, 2022, 5:52pm UTC](https://community.cesium.com/t/testing-cesium-in-jest/20977/1 "2022-10-27T17:52:09Z")

</div>

Hi,  
I’ve been playing around with testing while using Cesium in a service within an angular application. I’m currently trying to test the application using cesium as follows:

```auto
  it('should instantiate cesium viewer', () => {    
    insantiateSpy = jest.spyOn(service, 'insantiateViewer');
    service.insantiateViewer(testElement);
    expect(insantiateSpy).toBeCalledTimes(1);
  });

```

But I’m getting this error regarding WebGL (I’ve already tried the mocking jest web gl node package with no success).

```auto
console.error
    Error constructing CesiumWidget.
    Visit <a href="http://get.webgl.org">http://get.webgl.org</a> to verify that your web browser and hardware support WebGL. Consider trying a different web browser or updating your video drivers. Detailed error information is below:
    TypeError: Cannot read properties of undefined (reading '0')
    TypeError: Cannot read properties of undefined (reading '0')
        at new Context (C:\test\node_modules\cesium\Build\CesiumUnminified\index.cjs:34546:73)
        at new Scene4 (C:\test\node_modules\cesium\Build\CesiumUnminified\index.cjs:201896:19)
        at new CesiumWidget (C:\test\node_modules\cesium\Build\CesiumUnminified\index.cjs:207024:19)
        at new Viewer (C:\test\node_modules\cesium\Build\CesiumUnminified\index.cjs:213111:24)
        at CesiumService.insantiateViewer (C:\test\src\app\geo\cesium.service.ts:47:19)
        at CesiumService.<anonymous> (C:\test\node_modules\jest-mock\build\index.js:839:25)
        at C:\test\node_modules\jest-mock\build\index.js:433:39
        at CesiumService.<anonymous> (C:\test\node_modules\jest-mock\build\index.js:441:13)
        at CesiumService.mockConstructor [as insantiateViewer] (C:\test\node_modules\jest-mock\build\index.js:154:19)
        at C:\test\src\app\geo\cesium.service.spec.ts:44:13
        at _ZoneDelegate.Object.<anonymous>._ZoneDelegate.invoke (C:\test\node_modules\zone.js\bundles\zone-testing-bundle.umd.js:409:30)
        at ProxyZoneSpec.Object.<anonymous>.ProxyZoneSpec.onInvoke (C:\test\node_modules\zone.js\bundles\zone-testing-bundle.umd.js:3830:43)
        at _ZoneDelegate.Object.<anonymous>._ZoneDelegate.invoke (C:\test\node_modules\zone.js\bundles\zone-testing-bundle.umd.js:408:56)
        at Zone.Object.<anonymous>.Zone.run (C:\test\node_modules\zone.js\bundles\zone-testing-bundle.umd.js:169:47)
        at Object.wrappedFunc (C:\test\node_modules\zone.js\bundles\zone-testing-bundle.umd.js:4330:34)
        at Promise.then.completed (C:\test\node_modules\jest-circus\build\utils.js:333:28)
        at new Promise (<anonymous>)
        at callAsyncCircusFn (C:\test\node_modules\jest-circus\build\utils.js:259:10)
        at _callCircusTest (C:\test\node_modules\jest-circus\build\run.js:277:40)
        at _runTest (C:\test\node_modules\jest-circus\build\run.js:209:3)
        at _runTestsForDescribeBlock (C:\test\node_modules\jest-circus\build\run.js:97:9)
        at _runTestsForDescribeBlock (C:\test\node_modules\jest-circus\build\run.js:91:9)
        at run (C:\test\node_modules\jest-circus\build\run.js:31:3)
        at runAndTransformResultsToJestFormat (C:\test\node_modules\jest-circus\build\legacy-code-todo-rewrite\jestAdapterInit.js:135:21)

```

Any attempt to mock Cesium seems to fall flat too, anybody have a solution to this problem?

---

<div class="post-metadata">

**Author:** ![Aristeidis\_Bampakos](https://sea2.discourse-cdn.com/cesium/user_avatar/community.cesium.com/aristeidis_bampakos/32/2013_2.png) [@Aristeidis\_Bampakos](https://community.cesium.com/u/Aristeidis_Bampakos)\
**Post date:** [October 31, 2022, 10:58am UTC](https://community.cesium.com/t/testing-cesium-in-jest/20977/2 "2022-10-31T10:58:39Z")

</div>

Hey @sebheron 👋 Can you share the implementation details of the `insantiateViewer` method?

---

<div class="post-metadata">

**Author:** ![sebheron](https://sea2.discourse-cdn.com/cesium/user_avatar/community.cesium.com/sebheron/32/10801_2.png) [@sebheron](https://community.cesium.com/u/sebheron)\
**Post date:** [November 1, 2022, 11:39am UTC](https://community.cesium.com/t/testing-cesium-in-jest/20977/3 "2022-11-01T11:39:20Z")

</div>

Sure

```auto
  instantiateViewer(element: Element): void {
    this.viewer = new Viewer(element, this.options);
    this.update = setInterval(() => this.updateViewer(), dayjs(1, 'second').millisecond());
  }

```

---

<div class="post-metadata">

**Author:** ![Aristeidis\_Bampakos](https://sea2.discourse-cdn.com/cesium/user_avatar/community.cesium.com/aristeidis_bampakos/32/2013_2.png) [@Aristeidis\_Bampakos](https://community.cesium.com/u/Aristeidis_Bampakos)\
**Post date:** [November 1, 2022, 1:33pm UTC](https://community.cesium.com/t/testing-cesium-in-jest/20977/4 "2022-11-01T13:33:43Z")

</div>

I spotted a typo in your test code which may be the cause of the problem. Your method is called `instantiateViewer` but in the unit test, you refer to a `insantiateViewer` method.

---

<div class="post-metadata">

**Author:** ![sebheron](https://sea2.discourse-cdn.com/cesium/user_avatar/community.cesium.com/sebheron/32/10801_2.png) [@sebheron](https://community.cesium.com/u/sebheron)\
**Post date:** [November 1, 2022, 4:16pm UTC](https://community.cesium.com/t/testing-cesium-in-jest/20977/5 "2022-11-01T16:16:21Z")

</div>

Good spot, that typo was fixed earlier today which is why the code doesn’t match up with the error.

I’ve ended up working around the error by wrapping the Viewer’s creation in a private method that I mock using jest.

So this method:

```auto
  private createViewer(element: Element): void {
    this.viewer = new Viewer(element, this.options);
  }

```

Is mocked like this:

```auto
createSpy = jest.spyOn(CesiumService.prototype as any, 'createViewer');
createSpy.mockImplementation(() => {});

```

It’s not an ideal solution, but it works as the Viewer is never created and thus the WebGL error is never thrown. It doesn’t help my code coverage so @Aristeidis_Bampakos if you have a smarter alternative I’d be open to it.

---

<div class="post-metadata">

**Author:** ![Aristeidis\_Bampakos](https://sea2.discourse-cdn.com/cesium/user_avatar/community.cesium.com/aristeidis_bampakos/32/2013_2.png) [@Aristeidis\_Bampakos](https://community.cesium.com/u/Aristeidis_Bampakos)\
**Post date:** [November 2, 2022, 10:30am UTC](https://community.cesium.com/t/testing-cesium-in-jest/20977/6 "2022-11-02T10:30:13Z")

</div>

Although I am not familiar with Jest testing, I think that it is not much different from Karma and Jasmine that I use. Your initial test code should work because you are spying on the `instantiateViewer` method so the viewer should not be created in the first place, which is kinda weird 🤔

According to the unit test of the `createViewer` method what if you could write the first one like this:

```auto
insantiateSpy = jest.spyOn(CesiumService.prototype as any, 'insantiateViewer');
insantiateSpy.mockImplementation(() => {});
service.insantiateViewer(testElement);
expect(insantiateSpy).toBeCalledTimes(1);

```

I am not sure if it will work (as I mentioned I am not familiar with Jest 🙃) but AFAICU it is similar.

BTW, I usually avoid involving `private` properties and methods in my unit tests 😉 I try to test only public ones but I can understand that this is not the case sometimes.

---

<div class="post-metadata">

**Author:** ![Gabby\_Getz](https://sea2.discourse-cdn.com/cesium/user_avatar/community.cesium.com/gabby_getz/32/7838_2.png) [@Gabby\_Getz](https://community.cesium.com/u/Gabby_Getz)\
**Post date:** [November 2, 2022, 5:58pm UTC](https://community.cesium.com/t/testing-cesium-in-jest/20977/7 "2022-11-02T17:58:24Z")

</div>

Hi there,

You may have trouble creating the `Viewer` with the default options if WebGL isn’t available in that environment, for example if you’re running your tests directly on the command line and not through an instance of the browser.

CesiumJS [optionally uses a WebGL stub in its unit tests](https://github.com/CesiumGS/cesium/blob/main/Specs/createViewer.js). You could probably do the same to get your tests up and running using `Specs/getWebGLStub.js`.

---

<div class="post-metadata">

**Author:** ![shane\_benlolo](https://sea2.discourse-cdn.com/cesium/user_avatar/community.cesium.com/shane_benlolo/32/8439_2.png) [@shane\_benlolo](https://community.cesium.com/u/shane_benlolo)\
**Post date:** [May 10, 2023, 4:53pm UTC](https://community.cesium.com/t/testing-cesium-in-jest/20977/8 "2023-05-10T16:53:33Z")

</div>

Hi Gabby,

It appears the link you’ve provided here has died. Can you please provide an updated link? I’d like to implement your suggestion.

Thank you!

---

<div class="post-metadata">

**Author:** ![Gabby\_Getz](https://sea2.discourse-cdn.com/cesium/user_avatar/community.cesium.com/gabby_getz/32/7838_2.png) [@Gabby\_Getz](https://community.cesium.com/u/Gabby_Getz)\
**Post date:** [May 10, 2023, 7:36pm UTC](https://community.cesium.com/t/testing-cesium-in-jest/20977/9 "2023-05-10T19:36:56Z")

</div>

Hi, the new link is:

> <https://github.com/CesiumGS/cesium/blob/main/packages/widgets/Specs/createViewer.js>

---

<div class="post-metadata">

**Author:** ![naftali123](https://sea2.discourse-cdn.com/cesium/user_avatar/community.cesium.com/naftali123/32/15710_2.png) [@naftali123](https://community.cesium.com/u/naftali123)\
**Post date:** [August 27, 2023, 12:22pm UTC](https://community.cesium.com/t/testing-cesium-in-jest/20977/10 "2023-08-27T12:22:07Z")

</div>

Hi Gabby,

I’ve attempted to implement the code you provided (for creating a CesiumJS Viewer with a WebGL stub) in my React (TypeScript + Resium) project. However, I’m still encountering the same error.  
Here is my code:  
"  
import getWebGLStub from “./getWebGLStub”;  
import { ContextOptions, Viewer, defaultValue } from “cesium”;

declare global {  
interface Window {  
webglStub?: boolean;  
}  
}

function createViewer(container: Element | string, options: Viewer.ConstructorOptions = {}) {  
options = defaultValue(options, {});  
options.contextOptions = defaultValue(options.contextOptions, {}) as ContextOptions;  
options.contextOptions.webgl = defaultValue(options.contextOptions.webgl, {});  
if (!!window.webglStub) {  
options.contextOptions.getWebGLStub = getWebGLStub;  
}

return new Viewer(container, options);  
}  
export default createViewer;  
"  
Could you please assist me in identifying what I might have missed or misconfigured?

Thank you.

---

<div class="post-metadata">

**Author:** ![Gabby\_Getz](https://sea2.discourse-cdn.com/cesium/user_avatar/community.cesium.com/gabby_getz/32/7838_2.png) [@Gabby\_Getz](https://community.cesium.com/u/Gabby_Getz)\
**Post date:** [August 28, 2023, 12:45pm UTC](https://community.cesium.com/t/testing-cesium-in-jest/20977/11 "2023-08-28T12:45:14Z")

</div>

You can omit the line `if (!!window.webglStub) {`. This a command line option for configuring CesiumJS specs that you likely don’t need.

---

<div class="post-metadata">

**Author:** ![naftali123](https://sea2.discourse-cdn.com/cesium/user_avatar/community.cesium.com/naftali123/32/15710_2.png) [@naftali123](https://community.cesium.com/u/naftali123)\
**Post date:** [September 4, 2023, 3:05pm UTC](https://community.cesium.com/t/testing-cesium-in-jest/20977/12 "2023-09-04T15:05:47Z")

</div>

Hi Gabby,

Thanks for your previous message, and I apologize for the delayed response.

I followed your advice and removed the line ‘if (!!window.webglStub) {’ as you suggested.

```auto
function createViewer(container: Element | string, options: Viewer.ConstructorOptions = {}) {
  options = defaultValue(options, {});
  options.contextOptions = defaultValue(options.contextOptions, {}) as ContextOptions;
  options.contextOptions.webgl = defaultValue(options.contextOptions.webgl, {});
  // if (!!window.webglStub) { <--
    options.contextOptions.getWebGLStub = getWebGLStub;
  // } <--

  return new Viewer(container, options);
}

```

However, I’m still stuck with the same error.

If you have any more ideas or suggestions on how to tackle this issue, I’d be incredibly grateful.

Thank you.

Naftali

---

<div class="post-metadata">

**Author:** ![Gabby\_Getz](https://sea2.discourse-cdn.com/cesium/user_avatar/community.cesium.com/gabby_getz/32/7838_2.png) [@Gabby\_Getz](https://community.cesium.com/u/Gabby_Getz)\
**Post date:** [September 5, 2023, 1:22pm UTC](https://community.cesium.com/t/testing-cesium-in-jest/20977/13 "2023-09-05T13:22:36Z")

</div>

Hi @naftali123, could you show or explain how `createViewer` is used in your tests?

---

<div class="post-metadata">

**Author:** ![naftali123](https://sea2.discourse-cdn.com/cesium/user_avatar/community.cesium.com/naftali123/32/15710_2.png) [@naftali123](https://community.cesium.com/u/naftali123)\
**Post date:** [September 5, 2023, 1:35pm UTC](https://community.cesium.com/t/testing-cesium-in-jest/20977/15 "2023-09-05T13:35:33Z")

</div>

```auto
import { Cartesian3, Entity } from "cesium";
import { getWindowEntityPosition } from "./Position";
import createViewer from "../../test/createViewer";

describe('Position', ()=>{
    const x = 4919371.272916047;
    const y = 233079.2863174796;
    const z = 4039480.6613124954;
    const position: Cartesian3 = new Cartesian3(x, y, z);
    test('call getWindowEntityPosition without crashing', () => {
        const container: HTMLElement = document.createElement("div");
        const viewer: any = createViewer(container);
        const entity: Entity = new Entity({ id: "test", position });
        const result = getWindowEntityPosition({ entity, viewer });
        expect(result).toBeDefined();
    });
})

```
