5

Having a component that uses the embedded geolocation feature to get coordinates, how can I mock the call in a Jest test?

The component's code work in the org:

...

get locationService () {
    return navigator.geolocation
}

...

getCurrentPosition () {
    if (this.locationService) {
        let component = this
        this.locationService.getCurrentPosition(position => {
            component.markers = [{
                location: {
                    Latitude: position.coords.latitude,
                    Longitude: position.coords.longitude
                },
                title: 'You are here!'
            }]
            component.coordinates.lat = position.coords.latitude
            component.coordinates.lon = position.coords.longitude
        })
    }
}

...

But how can I test it, since having the following mock implementation results in an error when calling afterEach?

it('Should display the coordinate.', () => {

    const mockGeolocation = {
        getCurrentPosition: jest.fn()
            .mockImplementation((success) => Promise.resolve(success({
                coords: {
                    latitude: 10,
                    longitude: 10
                }
            })))
    }

    navigator.geolocation = mockGeolocation

    ...


    ... rest of the test goes below
})

The error on afterEach is this one on the terminal:

Assert Violation: undefined is not a vm.

      36 |     afterEach(() => {
      37 |         while (document.body.firstChild) {
    > 38 |             document.body.removeChild(document.body.firstChild)
         |             ^
      39 |         }
      40 |         jest.clearAllMocks()
      41 |     })

The error doesn't show up if I comment out the line that assigns the mockGeolocation object to the navigator.geolocation:

// navigator.geolocation = mockGeolocation
4
  • I copied over the goelocation mock and a simplified version of your getCurrentPosition method and I'm unable to reproduce the error. Have you tried running your test with a debugger attached to see if there's any other errors being thrown that could give some clues? May 13, 2019 at 20:24
  • I can't, but can you share your code? May 13, 2019 at 21:04
  • 1
    Sure, I added the code to a fork of lwc-recipes. You can checkout the branch below and after installing run npm run test:unit -- force-app/main/default/lwc/hello/ github.com/trevor-bliss/lwc-recipes/commit/… May 13, 2019 at 22:41
  • Let's move the conversation to GitHub then. I posted a comment with a piece of code there. May 13, 2019 at 23:43

1 Answer 1

1

Most info copied from discussion on the sample git commit here.

The technique you used to mock out the navigator.geolocation API is fine. The relevant code block from the original question is the following:

const mockGeolocation = {
    getCurrentPosition: jest.fn().mockImplementation((success) => 
        Promise.resolve(
            success({
                coords: {
                    latitude: 10,
                    longitude: 10
                }
            })
        )
    )
}

navigator.geolocation = mockGeolocation

The error referenced in the question is because a property was attempted to be accessed which did not have the @api decorator attached to it, making it a private property and inaccessible from the test case.

1
  • But this is only a mock for success function. How do you mock the error function? I tried somethind like this: getCurrentPosition: jest.fn() .mockImplementationOnce(error => Promise.reject(error(new Error('whaaaat')))), But my error fucntion code gets never reached.
    – Juuro
    Aug 11, 2020 at 10:59

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .