'How to use Jest useFakeTimers with RXJS?
My application is primarily using React Redux. We have a few places that use RXJS to simplify things. I just started using jest.useFakeTimers
.
I realized that given code like this from(anAsyncMethod).pipe(timeout(FETCH_TOKEN_TIMEOUT))
will trigger a timeout error the second jest.runAllTimers();
fires in my afterEach
.
The relevant stack is here:
stack: 'Error: \n' +
' at _super (webpack-internal:///../../node_modules/rxjs/dist/esm5/internal/util/createErrorClass.js:6:26)\n' +
' at new TimeoutErrorImpl (webpack-internal:///../../node_modules/rxjs/dist/esm5/internal/operators/timeout.js:21:9)\n' +
' at timeoutErrorFactory (webpack-internal:///../../node_modules/rxjs/dist/esm5/internal/operators/timeout.js:66:11)\n' +
' at AsyncAction.eval (webpack-internal:///../../node_modules/rxjs/dist/esm5/internal/operators/timeout.js:44:84)\n' +
' at AsyncAction.eval (webpack-internal:///../../node_modules/rxjs/dist/esm5/internal/util/caughtSchedule.js:7:21)\n' +
' at AsyncAction._execute (webpack-internal:///../../node_modules/rxjs/dist/esm5/internal/scheduler/AsyncAction.js:65:18)\n' +
' at AsyncAction.execute (webpack-internal:///../../node_modules/rxjs/dist/esm5/internal/scheduler/AsyncAction.js:53:26)\n' +
' at AsyncScheduler.flush (webpack-internal:///../../node_modules/rxjs/dist/esm5/internal/scheduler/AsyncScheduler.js:26:33)\n' +
' at callTimer (/Users/dstein/Repositories/uxp-plugin/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:729:24)\n' +
' at Object.next (/Users/dstein/Repositories/uxp-plugin/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1409:17)\n' +
' at Object.runAll (/Users/dstein/Repositories/uxp-plugin/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1468:23)\n' +
' at FakeTimers.runAllTimers (/Users/dstein/Repositories/uxp-plugin/node_modules/@jest/fake-timers/build/modernFakeTimers.js:75:19)\
Is there any way to work around this issue?
Solution 1:[1]
well looks like anAsyncMethod
takes longer than FETCH_TOKEN_TIMEOUT
therefore the error is thrown, this is expected.
when you subscribe to your observable you should check for errors:
from(anAsyncMethod).pipe(timeout(FETCH_TOKEN_TIMEOUT)).subscribe(
res => console.log('ok'),
err => console.error('timeout')
);
or you can catch the error
from(anAsyncMethod).pipe(
timeout(FETCH_TOKEN_TIMEOUT),
catchError(error => of(`Request timed out after: ${FETCH_TOKEN_TIMEOUT}`))
);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Zerotwelve |