I already am implementing unit tests using redux-mock-store
.
I would like to perform an integration test suite on a react-native app that uses store singletons just fine. However even though console.log
s reach so far as the reducer function (and seems to be working correctly) state on the store does not change.
// __tests__/things.js
jest.mock('../app/store')
import 'react-native'
import * as selectors from '../app/selectors'
import * as sagas from '../app/sagas'
import { store } from '../app/store'
describe('Things', () => {
it('should toggle', async () => {
const previousCounter = selectors.count()
await sagas.increment()
expect(store.getState().count).toEqual(previousCounter)
})
})
Meanwhile the mock store implementation:
// __mocks__
import { createStore } from 'redux'
import rootReducer from '../reducers'
export const store = createStore(rootReducer, {})
EDIT: A sample reducer
// app/reducers.js
function rootReducer (state = { count: 0 }, action = {}) {
const count = state.count + 1
return { ...state, count }
}
Everything works great, but the state does not change. If I implement an observer by subscribing to the store, I see the action series being dispatched.
I'll answer my question as a mean for others to work on this casuistic.
As in many other tutorials and guides, store singletons are discouraged. Which I understand is a matter of isolating dependencies and components. However if you still decide to use it for comfort –as we do– you'll need to mock the component when required from other deps, as they are not going to be mocked recursively.
So apart form having a similar to this, folder structure...
You'll need to export the mocked version, for those deps that require './store.js' at the same time.
This way, whenever
store.js
is required during tests, it will recursively choose the mock version over the real one.Probably store singletons need a little more advocacy to be chosen as a mainstream redux practice. Should not be considered an anti-pattern.