reduxjs/redux-mock-store

Make getState controllable

toan2406 opened this issue ยท 4 comments

Hi,
Thanks for the great lib. I'm using it to test my middlewares. But since in middleware I can access the API getState, could you make it more controllable by passing the actions along when calling getState

getState () {
    return isFunction(getState) ? getState(actions) : getState
},

So I can use it like this

const store = mockStore(actions => {
    const lastAction = actions[actions.length - 1]
    if (!lastAction) return {}
    if (lastAction.type === 'GET_FOO') return { foo: 'foo' }
})
store.getState() // {}
store.dispatch({ type: 'GET_FOO' })
store.getState() // { foo: 'foo' }

What do you think? If you're OK with it I can make a PR ๐Ÿ˜Š

@toan2406 that's what I would like to have too.

store.getState() // {}
store.dispatch({ type: 'GET_FOO' })
store.getState() // { foo: 'foo' }

This part of the code is invalid from the perspective of immutable event dispatching: you are dispatching one action but getting from the store another one.

@toan2406 Could you please describe the problem that you are facing more in details, so we can try to come up with the solution which would not break the ideas behind redux?

@dmitry-zaets Thanks for your reply. For example I want to simulate the redux example, which is:

store.getState() // 0
store.dispatch({ type: 'INCREMENT' })
store.dispatch({ type: 'INCREMENT' })
store.dispatch({ type: 'DECREMENT' })
store.getState() // 1

So with the actions as the argument for the callback when I create the mockStore, I can do something like this:

const store = mockStore(actions => {
    const defaultState = 0
    return actions.reduce((result, action) => {
        if (action.type === 'INCREMENT') return result + 1
        if (action.type === 'DECREMENT') return result - 1
        return result
    }, defaultState)
})

For the example on the above comment, maybe I should make it clearer like this:

store.dispatch({ type: 'GET_FOO', payload: fetch('/get_foo_api') })
// after promise is resolved and store is updated; for the mock can just make it synchronously
store.getState() // { foo: 'foo' }

I don't understand about immutable event dispatching. Could you pls give more info about it? Thanks alot.

@toan2406 Thanks a lot for the explanation. My bad, I've misunderstood the initial explanations.

Implemented in #109

Until the PR is merged, you can achieve the same by calling store.getActions():

const store = mockStore( () => {
    const actions = store.getActions()
    const lastAction = actions[actions.length - 1]
    if (!lastAction) return {}
    if (lastAction.type === 'GET_FOO') return { foo: 'foo' }
})
store.getState() // {}
store.dispatch({ type: 'GET_FOO' })
store.getState() // { foo: 'foo' }