kentcdodds/testing-react-apps

Why promise is needed in exercise 6?

pom421 opened this issue · 4 comments

window.navigator.geolocation.getCurrentPosition.mockImplementation(

Hi Kent,

I don't understand why the promise is needed for the 6th exercise.

Won't this be enough ?

      window.navigator.geolocation.getCurrentPosition = jest.fn().mockImplementation(
              (success, error) => success(fakePosition))

Or maybe are you trying to introduce some async work to be closer to reality?

Exactly, because the API is async, I want to make sure that any code using it is also async. Additionally, if we just call success instantly, then we won't be able to assert the loading state :)

That makes sense, thx Kent! 👍 😄

https://github.com/bsonntag/react-use-geolocation/blob/main/src/use-current-position.js

Here that external library calls the getCurrentPosition() method inside an useEffect. In that case, at the time component is mounted, it should be rendering the Spinner.
Can't we assume the first expect will see this spinner?
Can't we assume the next 'expect' will see this spinner automatically goes away(If you don't use a promise to resolve as mentioned in the original question)?

@sashrika all useEffects are called synchronously when using React Testing Library because we auto-wrap everything in act. This is intentional because that's basically the user's experience anyway (it's extremely rare that a user would ever observe the state of the app between render and useEffect. So if you give it a try you'll notice that no, you can't call the callback synchronously and assert the loading state as well.