Description
I created logic to verify something after 10 seconds, for instance:
export const validateSomething = createLogic({
name: 'validateSomething',
type: VALIDATE_SOMETHING,
cancelType: CANCEL_VALIDATE_SOMETHING,
process({ getState, action, cancelled$ }, dispatch, done) {
const timeout = setTimeout(() => {
const something = getSomeThing(getState())
something ? dispatch(actionA()) : dispatch(actionB())
done()
}, 10000)
cancelled$.subscribe(() => {
clearTimeout(timeout)
done()
})
}
})
as you can see I added cancelType which allows to cancel this logic before it reaches 10sec
I'm using Jest and redux-logic-test to test logics, However, there are two issues I ran into.
First, because whenComplete
resolved only when done()
is called. This means that the test should wait until the timers is over and only then call done()
(at least 10 sec per unit-testing).
Ok, I know!...why don't use jest.useFakeTimers()
? well, it looks like there's some problem with jest.useFakeTimers
and some of the timers RxJs
operators.
Anyway, useFakeTimers
causes the test freeze until you invoke jest.runAllTimers()
(it make sense why this happens, because jest.useFakeTimers()
freeze all timers until you call jest.runAllTimers()
or some another jest timer helpers) but now the test totally freezes because of the real timer(from the logic implementation) which wrap by jest.useFakeTimers()
but created after the first jest.runAllTimers()
so nothing happen.
Second, it related to the same problem with whenComplete which resolved only when done()
is called. so imagine that I want to test cancelType, what I expect for?
a. create createMockStore
,
b. dispatch 'VALIDATE_SOMETHING',
c. dispatch CANCEL_VALIDATE_SOMETHING
but when you dispatch the first action(in this case VALIDATE_SOMETHING), whenComplete
wait until the done() will call and then resolved. it means you have to wait until the timer finish so you never cancel the logic in test.
Test code:
describe('test: unit tests', () => {
test('should run properly', async () => {
jest.useFakeTimers()
const store = createMockStore({ logic: [validateSomething], reducer: rootReducer})
store.dispatch({ type: 'VALIDATE_SOMETING' })
jest.runAllTimers()
const expectedActions = []
await store.whenComplete()
expect([]).toEqual(expectedActions)
})
})
when using jest.useFakeTimers()
and jest.runAllTimers()
getting this error
javascript console.error node_modules/redux-logic/build-lib/createCancelled$.js:74
warning: logic (validateSegmentsPushDataArrivedBeforeTimeoutLogic) is still running after 60s, forget
to call done()? For non-ending logic, set warnTimeout: 0```