I am trying to write unit tests for a redux application. I have a common store.js
:
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './root-reducer';
export default createStore(rootReducer, applyMiddleware(thunk));
And the test file:
// necessary imports and mocks
describe('store', () => {
beforeEach(() => {
redux.createStore.mockClear();
redux.applyMiddleware.mockClear();
jest.resetModules()
});
it('should create the store properly', async () => {
const stubMiddleware = jest.fn();
redux.applyMiddleware.mockImplementation(() => stubMiddleware);
await import('./store');
expect(redux.createStore).toHaveBeenCalledTimes(1);
expect(redux.createStore).toHaveBeenCalledWith(rootReducer, stubMiddleware);
});
it('should apply thunk middleware', async () => {
redux.applyMiddleware.mockImplementation(() => {});
await import('./store');
expect(redux.applyMiddleware).toHaveBeenCalledTimes(1);
expect(redux.applyMiddleware).toHaveBeenCalledWith(thunk);
});
});
Unfortunately, the second test case will fail, since the store module is evaluated only once at the first import and I clear all the mocks after each test.
Actually the problem is pretty specific, but the question is broader. We have many tools where we need to add side-effects to our modules, like here, creating a store.
How can these side-effects get tested? My first solution was exporting a getStore()
method which was kind of an implementation of the singleton DP, but again, in that case, the module was stateful by the singleton instance which might require re-evaluation in certain cases.
I've also tried jest.resetModules()
and jest.isolateModules()
but they didn't help.