Skip to content

Instantly share code, notes, and snippets.

@Rokt33r
Last active July 3, 2017 02:22
Show Gist options
  • Save Rokt33r/92be940a9d6bddccf99fa7d11131f451 to your computer and use it in GitHub Desktop.
Save Rokt33r/92be940a9d6bddccf99fa7d11131f451 to your computer and use it in GitHub Desktop.
Async Saga test
import {
createSaga
} from '../lib'
import {
createStore,
applyMiddleware,
} from 'redux'
import {
PureAction,
createActionCreator,
} from 'typed-redux-kit'
const delay = (time: number) => {
return new Promise((resolve) => {
setTimeout(function() {
resolve(true)
}, time);
})
}
interface State {
check: boolean
}
const initialState ={
check: false
}
enum ActionType {
Request = 'REQ',
Response = 'RES'
}
interface RequestAction extends PureAction<ActionType.Request> {}
interface ResponseAction extends PureAction<ActionType.Response> {}
type Action = RequestAction | ResponseAction
const ActionCreators = {
request: createActionCreator<RequestAction>(ActionType.Request),
response: createActionCreator<ResponseAction>(ActionType.Response),
}
const reducer = (state: State = initialState, action: Action) => {
switch (action.type) {
case ActionType.Request:
return {
check: !state.check
}
}
return state
}
const saga = createSaga()
test('Oh my Async Saga', async () => {
const store = createStore(reducer, applyMiddleware(saga.middleware))
const toBeExecutedBeforeDispatch = jest.fn()
const toBeExecutedBeforeLoopEnd = jest.fn()
await new Promise((resolve, reject) => {
// To make sure the timing to assert, we need to use generator
const testGenerator = function * (): IterableIterator<any> {
yield
expect(toBeExecutedBeforeDispatch).toBeCalled()
console.log(1.5)
yield
expect(toBeExecutedBeforeLoopEnd).toBeCalled()
expect(store.getState()).toEqual({
check: true
})
console.log(4.5)
// Run next loop
store.dispatch(ActionCreators.request())
// These yield ensure the second loop is end.
yield
yield
// Check again the second dispatching work as we expected
expect(store.getState()).toEqual({
check: false
})
// Finish test
resolve()
}
const gen = testGenerator()
gen.next()
saga.run(async ({
take,
put
}) => {
while (true) {
console.log(1)
toBeExecutedBeforeDispatch()
gen.next()
const action = await take<RequestAction>(ActionType.Request)
expect(action).toEqual({
type: ActionType.Request
})
console.log(2)
await delay(1000)
console.log(3)
// The below put will be executed like non-block(actually executed at next tick because we use async func)
await put(ActionCreators.response())
// Also, you can use put without await
// put(ActionCreators.response())
console.log(4)
toBeExecutedBeforeLoopEnd()
gen.next()
}
})
store.dispatch(ActionCreators.request())
})
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment