No response when using `jest.useFakeTimers()` with axios and msw
See original GitHub issueDescribe the bug
My app uses Svelte with Axios to fetch data from a REST API endpoint. I noticed that Axios didn’t sometimes wait long enough for the request and it timed out. Now I increased the Axios’ timeout to 12000 ms and wanted to verify it with tests that it actually waits for long enough for the request.
So I mocked the API with msw for the basic test that it actually works. No problems there. And when I add the delay to my msw mocked API, it works too, I just need to increase the test’s timeout value so it actually waits long enough.
Which brings me to my point: I don’t really want to wait for that long to verify that the Axios’ 12 second timeout actually works. So here’s where I wanted to use the jest’s useFaketimers
method but I just can’t get it to work. Even when trying to advance the mocked timer with every command I found in jest, the response never comes.
Environment
msw: 0.35.0
nodejs: 14.17.3
npm: 7.24.0
packages.json deps
"devDependencies": {
"@jest/types": "^27.2.5",
"@testing-library/dom": "^8.10.1",
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/svelte": "^3.0.3",
"@tsconfig/svelte": "^2.0.1",
"@types/jest": "^27.0.2",
"@types/node": "^16.11.6",
"@types/testing-library__jest-dom": "^5.14.1",
"@typescript-eslint/eslint-plugin": "^4.33.0",
"@typescript-eslint/parser": "^4.33.0",
"eslint": "^7.32.0",
"eslint-import-resolver-typescript": "^2.5.0",
"eslint-plugin-import": "^2.25.2",
"eslint-plugin-svelte3": "^3.2.1",
"eslint-plugin-testing-library": "^4.12.4",
"jest": "^27.3.1",
"msw": "^0.35.0",
"svelte": "^3.44.0",
"svelte-check": "^2.2.7",
"svelte-jester": "^2.1.5",
"svelte-preprocess": "^4.9.8",
"ts-jest": "^27.0.7",
"ts-node": "^10.4.0",
"tslib": "^2.3.1",
"typescript": "^4.4.4"
},
"dependencies": {
"axios": "^0.24.0"
}
Please also provide your browser version.
Not really browser related but sure:
- Chrome 95.0.4638.69 (Official Build) (64-bit)
- Firefox 94.0.1 (64-bittinen)
To Reproduce
Steps to reproduce the behavior:
- use axios to fetch data from a REST API endpoint
- mock the API with msw
- add a delay to the msw mocked API
- use
jest.useFakeTimers()
to mock timers - use
jest.advanceTimersByTime()
to pass the time forward until there should be an answer from the delayed API request - the test times out with an error like
Unable to find an element with the text
or similar
Expected behavior
jest successfully mocks timers and skips the time so the test doesn’t timeout.
Reproduction repo
https://github.com/asode/msw-usefaketimers
Failing test code: https://github.com/asode/msw-usefaketimers/blob/main/src/App.test.ts#L43
Failing test run: https://github.com/asode/msw-usefaketimers/runs/4106445180#step:4:27
Issue Analytics
- State:
- Created 2 years ago
- Reactions:4
- Comments:14 (5 by maintainers)
Top GitHub Comments
As we’re using
timers
instead, I’d expect that Jest’s fake timers had no effect on the library. We need to take a deeper dive into howjest.useFakeTimers()
actually works, what modules it stubs, etc.I believe that historically, the main purpose to use the custom
timers
package was to opt-out from usingsetTimeout
directly. MSW wraps all mocked responses insetTimeout
and uses either the custom delay duration or0
when no delay is intended. It’s because of that zero that we still needed to allow immediate mocked responses when using fake times in Jest.To give you a better perspective, this code will never resolve if we use
setTimeout
directly:We may omit the
setTimeout
usage for no-delay scenarios, which should allow us to both respect the fake timers (and demand you advance them to support delayed responses) and make immediate responses happen correctly while using fake timers.I’d be thankful if somebody could give that approach a try. Here’s the related logic that uses
setTimeout
:https://github.com/mswjs/msw/blob/f6fbd6c94d86d54ee13d20f0128589332cbddcbf/src/utils/handleRequest.ts#L122-L130
timers
package from rollup.config.js.setTimeout
only when the custom delay has been sent.Hi, I feel like my issue may be related to this so I post it here and maybe it wil help someone.
I had a problem while testing the React Native TextInput component with debouncing and redux-toolkit useQuery hook (for data fetching) and I’ve managed to test it this way. It seems kind of hacky though
I upgraded jest to the latest “^27.4.2” version and used it as below.