Skip to content

Commit 63ae1c5

Browse files
authored
Merge pull request #116 from mayank23/master
conform more to basic redux behavior for dispatch.
2 parents c61d95f + 9945cb2 commit 63ae1c5

File tree

3 files changed

+69
-51
lines changed

3 files changed

+69
-51
lines changed

package.json

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "redux-mock-store",
3-
"version": "1.3.0",
3+
"version": "1.4.0",
44
"description": "A mock store for testing your redux async action creators and middleware",
55
"main": "lib/index.js",
66
"scripts": {
@@ -30,5 +30,8 @@
3030
"rimraf": "^2.4.3",
3131
"sinon": "^1.17.2",
3232
"standard": "^7.1.2"
33+
},
34+
"dependencies": {
35+
"lodash.isplainobject": "^4.0.6"
3336
}
3437
}

src/index.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { applyMiddleware } from 'redux'
2+
import isPlainObject from 'lodash.isplainobject'
23

34
const isFunction = arg => typeof arg === 'function'
45

@@ -18,9 +19,10 @@ export default function configureStore (middlewares = []) {
1819
},
1920

2021
dispatch (action) {
21-
if (typeof action === 'undefined') {
22+
if (!isPlainObject(action)) {
2223
throw new Error(
23-
'Actions may not be an undefined.'
24+
'Actions must be plain objects. ' +
25+
'Use custom middleware for async actions.'
2426
)
2527
}
2628

test/index.js

+61-48
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import thunk from 'redux-thunk'
66
import mockMiddleware from './mock/middleware'
77
import configureStore from '../src'
88

9-
const mockStore = configureStore([thunk])
9+
const mockStore = configureStore()
1010

1111
describe('redux-mock-store', () => {
1212
describe('getState', () => {
@@ -40,11 +40,21 @@ describe('redux-mock-store', () => {
4040
})
4141
})
4242

43-
it('should throw an error when action is undefined', () => {
43+
it('should throw an error when the action is undefined', () => {
4444
const store = mockStore({})
4545

4646
expect(() => { store.dispatch(undefined) }).toThrow(
47-
'Actions may not be an undefined.'
47+
'Actions must be plain objects. ' +
48+
'Use custom middleware for async actions.'
49+
)
50+
})
51+
52+
it('should throw an error when the action is not a plain object', () => {
53+
const store = mockStore({})
54+
55+
expect(() => { store.dispatch(() => {}) }).toThrow(
56+
'Actions must be plain objects. ' +
57+
'Use custom middleware for async actions.'
4858
)
4959
})
5060

@@ -70,51 +80,6 @@ describe('redux-mock-store', () => {
7080
expect(first).toBe(action)
7181
})
7282

73-
it('handles async actions', (done) => {
74-
function increment () {
75-
return {
76-
type: 'INCREMENT_COUNTER'
77-
}
78-
}
79-
80-
function incrementAsync () {
81-
return dispatch => {
82-
return Promise.resolve()
83-
.then(() => dispatch(increment()))
84-
}
85-
}
86-
87-
const store = mockStore({})
88-
89-
store.dispatch(incrementAsync())
90-
.then(() => {
91-
expect(store.getActions()[0]).toEqual(increment())
92-
done()
93-
})
94-
})
95-
96-
it('should call the middleware', () => {
97-
const spy = sinon.spy()
98-
const middlewares = [mockMiddleware(spy)]
99-
const mockStoreWithMiddleware = configureStore(middlewares)
100-
const action = { type: 'ADD_ITEM' }
101-
102-
const store = mockStoreWithMiddleware()
103-
store.dispatch(action)
104-
expect(spy.called).toBe(true)
105-
})
106-
107-
it('should handle when test function throws an error', (done) => {
108-
const store = mockStore({})
109-
const error = { error: 'Something went wrong' }
110-
111-
store.dispatch(() => Promise.reject(error))
112-
.catch(err => {
113-
expect(err).toEqual(error)
114-
done()
115-
})
116-
})
117-
11883
it('clears the actions', () => {
11984
const action = { type: 'ADD_ITEM' }
12085
const store = mockStore({})
@@ -177,4 +142,52 @@ describe('redux-mock-store', () => {
177142
expect(() => store.replaceReducer(123))
178143
.toThrow('Expected the nextReducer to be a function.')
179144
})
145+
146+
describe('store with middleware', () => {
147+
const mockStoreWithMiddleware = configureStore([thunk])
148+
it('handles async actions', (done) => {
149+
function increment () {
150+
return {
151+
type: 'INCREMENT_COUNTER'
152+
}
153+
}
154+
155+
function incrementAsync () {
156+
return dispatch => {
157+
return Promise.resolve()
158+
.then(() => dispatch(increment()))
159+
}
160+
}
161+
162+
const store = mockStoreWithMiddleware({})
163+
164+
store.dispatch(incrementAsync())
165+
.then(() => {
166+
expect(store.getActions()[0]).toEqual(increment())
167+
done()
168+
})
169+
})
170+
171+
it('should handle when test function throws an error', (done) => {
172+
const store = mockStoreWithMiddleware({})
173+
const error = { error: 'Something went wrong' }
174+
175+
store.dispatch(() => Promise.reject(error))
176+
.catch(err => {
177+
expect(err).toEqual(error)
178+
done()
179+
})
180+
})
181+
182+
it('should call the middleware', () => {
183+
const spy = sinon.spy()
184+
const middlewares = [mockMiddleware(spy)]
185+
const mockStoreWithCustomMiddleware = configureStore(middlewares)
186+
const action = { type: 'ADD_ITEM' }
187+
188+
const store = mockStoreWithCustomMiddleware()
189+
store.dispatch(action)
190+
expect(spy.called).toBe(true)
191+
})
192+
})
180193
})

0 commit comments

Comments
 (0)