Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test hangs waiting for promise to resolve #621

Closed
6 tasks done
slauzinho opened this issue Jan 24, 2022 · 13 comments · Fixed by #639
Closed
6 tasks done

Test hangs waiting for promise to resolve #621

slauzinho opened this issue Jan 24, 2022 · 13 comments · Fixed by #639

Comments

@slauzinho
Copy link

slauzinho commented Jan 24, 2022

Describe the bug

Using the new vi.setSystemTime I added vi.useFakeTimers(); but this seems to be breaking my async tests.
The tests now wait for the promise to resolve, and since we are using fake timers it never happens.

I saw an example that uses await flushPromises() but this doesn't seem to do the trick.

Reproduction

https://stackblitz.com/edit/github-u4au2p?file=src/stores/counter.js

Run yarn test and see the test hang

System Info

System:
    OS: macOS 10.15.6
    CPU: x64 Intel(R) Core(TM) i7-8700K CPU @ 3.70GHz
    Memory: 204.80 MB / 32.00 GB
    Shell: 5.7.1 - /bin/zsh
  Binaries:
    Node: 16.6.1 - ~/.nvm/versions/node/v16.6.1/bin/node
    Yarn: 1.22.5 - ~/.yarn/bin/yarn
    npm: 8.3.0 - ~/.nvm/versions/node/v16.6.1/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  npmPackages:
    vite: ^2.7.12 => 2.7.13 
    vitest: ^0.2.1 => 0.2.1

Used Package Manager

yarn

Validations

@Demivan
Copy link
Member

Demivan commented Jan 24, 2022

Problem is caused by your usage of setImmediate to resolve the promise. To advance timers and run setImmediate you can run vi.runAllTimers and it works fine:
https://stackblitz.com/edit/github-u4au2p-5duhjr?file=src%2Fstores%2Fcounter.js

@slauzinho
Copy link
Author

What's the approach when using a real api call?

https://stackblitz.com/edit/github-u4au2p-urgmzt?file=src/stores/counter.js

@sheremet-va
Copy link
Member

sheremet-va commented Jan 24, 2022

What's the approach when using a real api call?

https://stackblitz.com/edit/github-u4au2p-urgmzt?file=src/stores/counter.js

You can follow guide from the docs or use any kind of mocking library to mock fetch call, for example vi-fetch or jest-fetch-mock. Or you can mannually mock it:

globalThis.fetch = vi.fn().mockReturnValue(data)

@slauzinho
Copy link
Author

Yeah I know I can mock fetch or library but I'm actually using MSW to avoid having to mock all my requests.

@sheremet-va
Copy link
Member

Yeah I know I can mock fetch or library but I'm actually using MSW to avoid having to mock all my requests.

That is what our guide recommends.

@slauzinho
Copy link
Author

slauzinho commented Jan 24, 2022

Yeah and MSW works fine with vitest. The issue is when I have to use useFakeTimers due to the new setSystemTime API released in 0.2.1.

With Jest I could just do:

jest.useFakeTimers('modern').setSystemTime(nee Date('2020-01-01'))

and it didn't hang.

If I understood correctly by using useFakeTimers I will have to mock the API request because otherwise the promise never resolves?

@sheremet-va
Copy link
Member

Yeah and MSW works fine with vitest. The issue is when I have to use useFakeTimers due to the new setSystemTime API released in 0.2.1.

If I understood correctly by using useFakeTimers I will have to mock the API request because otherwise the promise never resolves?

Usually no, It shouldn't, if implementation doesn't have something like await new Promise((resolve) => setTimeout(resolve))

The issue happens only with MSW?

We are using the same API jest uses, so I struggle to see where it came from.

@sheremet-va
Copy link
Member

sheremet-va commented Jan 24, 2022

Hanging actually comes from response.json, and not from response itself.

@sheremet-va
Copy link
Member

With Jest I could just do:

jest.useFakeTimers('modern').setSystemTime(nee Date('2020-01-01'))

and it didn't hang.

Maybe you were using another package for fetch? Happy-dom uses node-fetch.

Using the new vi.setSystemTime I added vi.useFakeTimers(); but this seems to be breaking my async tests.
The tests now wait for the promise to resolve, and since we are using fake timers it never happens.

This is expected behaviour, unfortunately. I recommend using mockdate package, if you relied on setMockedDate before.

@slauzinho
Copy link
Author

slauzinho commented Jan 24, 2022

Maybe you were using another package for fetch? Happy-dom uses node-fetch.

I'm using Axios

Using the new vi.setSystemTime I added vi.useFakeTimers(); but this seems to be breaking my async tests.
The tests now wait for the promise to resolve, and since we are using fake timers it never happens.

This is expected behaviour, unfortunately. I recommend using mockdate package, if you relied on setMockedDate before.

Thanks I will use mockdate, I actually had it install and was running on another test file without issues.

Thank once again for your help 👍

@Demivan
Copy link
Member

Demivan commented Jan 25, 2022

@sheremet-va would it be a good idea to bring back setMockedDate for current date mocking? I feel like fake-timers would be an overkill for most users.

@sheremet-va
Copy link
Member

I do agree it's an overkill, but don't like having two methods for this.

We can use mockdate if timers aren't mocked in setSytemTime and reset it inside useRealTimers

@Demivan
Copy link
Member

Demivan commented Jan 25, 2022

We can use mockdate if timers aren't mocked in setSytemTime and reset it inside useRealTimers

That is a great idea.

antfu added a commit that referenced this issue Jan 27, 2022
chaii3 pushed a commit to chaii3/vitest that referenced this issue May 13, 2022
@github-actions github-actions bot locked and limited conversation to collaborators Jun 22, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants