Skip to content

Commit

Permalink
reduxjs#1944 Converting tests from Mocha to Jest
Browse files Browse the repository at this point in the history
Added Jest dependencies
Removed expect from files
Updated mocks to use `jest.fn()`
Current `expect.spyOn` replacement can be improved on
TODO: Fix linter not to complain about using `console`
  • Loading branch information
HeinrichFilter committed Sep 13, 2016
1 parent 5205c61 commit 9af86bd
Show file tree
Hide file tree
Showing 9 changed files with 152 additions and 134 deletions.
7 changes: 6 additions & 1 deletion package.json
Expand Up @@ -18,7 +18,7 @@
"lint": "npm run lint:src && npm run lint:examples",
"lint:src": "eslint src test build",
"lint:examples": "eslint examples",
"test": "cross-env BABEL_ENV=commonjs mocha --compilers js:babel-register --recursive",
"test": "jest",
"test:watch": "npm test -- --watch",
"test:cov": "cross-env BABEL_ENV=commonjs babel-node $(npm bin)/isparta cover $(npm bin)/_mocha -- --recursive",
"test:examples": "cross-env BABEL_ENV=commonjs babel-node examples/testAll.js",
Expand Down Expand Up @@ -73,6 +73,7 @@
"babel-cli": "^6.3.15",
"babel-core": "^6.3.15",
"babel-eslint": "^4.1.6",
"babel-jest": "^15.0.0",
"babel-loader": "^6.2.0",
"babel-plugin-check-es2015-constants": "^6.3.13",
"babel-plugin-transform-es2015-arrow-functions": "^6.3.13",
Expand Down Expand Up @@ -105,6 +106,7 @@
"gitbook-cli": "^2.3.0",
"glob": "^6.0.4",
"isparta": "^4.0.0",
"jest": "^15.1.1",
"mocha": "^2.2.5",
"rimraf": "^2.3.4",
"rxjs": "^5.0.0-beta.6",
Expand All @@ -125,5 +127,8 @@
"transform": [
"loose-envify"
]
},
"jest": {
"testRegex": "(/test/.*\\.spec.js)$"
}
}
2 changes: 1 addition & 1 deletion test/.eslintrc
@@ -1,5 +1,5 @@
{
"env": {
"mocha": true
"jest": true
}
}
11 changes: 5 additions & 6 deletions test/applyMiddleware.spec.js
@@ -1,4 +1,3 @@
import expect from 'expect'
import { createStore, applyMiddleware } from '../src/index'
import * as reducers from './helpers/reducers'
import { addTodo, addTodoAsync, addTodoIfEmpty } from './helpers/actionCreators'
Expand All @@ -13,15 +12,15 @@ describe('applyMiddleware', () => {
}
}

const spy = expect.createSpy(() => {})
const spy = jest.fn(() => {})
const store = applyMiddleware(test(spy), thunk)(createStore)(reducers.todos)

store.dispatch(addTodo('Use Redux'))
store.dispatch(addTodo('Flux FTW!'))

expect(spy.calls.length).toEqual(1)
expect(spy.mock.calls.length).toEqual(1)

expect(Object.keys(spy.calls[0].arguments[0])).toEqual([
expect(Object.keys(spy.mock.calls[0][0])).toEqual([
'getState',
'dispatch'
])
Expand All @@ -37,11 +36,11 @@ describe('applyMiddleware', () => {
}
}

const spy = expect.createSpy(() => {})
const spy = jest.fn(() => {})
const store = applyMiddleware(test(spy), thunk)(createStore)(reducers.todos)

return store.dispatch(addTodoAsync('Use Redux')).then(() => {
expect(spy.calls.length).toEqual(2)
expect(spy.mock.calls.length).toEqual(2)
})
})

Expand Down
1 change: 0 additions & 1 deletion test/bindActionCreators.spec.js
@@ -1,4 +1,3 @@
import expect from 'expect'
import { bindActionCreators, createStore } from '../src'
import { todos } from './helpers/reducers'
import * as actionCreators from './helpers/actionCreators'
Expand Down
67 changes: 41 additions & 26 deletions test/combineReducers.spec.js
@@ -1,4 +1,3 @@
import expect from 'expect'
import { combineReducers } from '../src'
import createStore, { ActionTypes } from '../src/createStore'

Expand Down Expand Up @@ -32,21 +31,24 @@ describe('Utils', () => {
})

it('warns if a reducer prop is undefined', () => {
const spy = expect.spyOn(console, 'error')
const preSpy = console.error
const spy = jest.fn(() => {})
console.error = spy

let isNotDefined
combineReducers({ isNotDefined })
expect(spy.calls[0].arguments[0]).toMatch(
expect(spy.mock.calls[0][0]).toMatch(
/No reducer provided for key "isNotDefined"/
)

spy.reset()
spy.mockClear()
combineReducers({ thing: undefined })
expect(spy.calls[0].arguments[0]).toMatch(
expect(spy.mock.calls[0][0]).toMatch(
/No reducer provided for key "thing"/
)

spy.restore()
spy.mockClear()
console.error = preSpy
})

it('throws an error if a reducer returns undefined handling an action', () => {
Expand Down Expand Up @@ -166,7 +168,7 @@ describe('Utils', () => {
})

const initialState = reducer(undefined, '@@INIT')
expect(reducer(initialState, { type: 'increment' })).toNotBe(initialState)
expect(reducer(initialState, { type: 'increment' })).not.toBe(initialState)
})

it('throws an error on first call if a reducer attempts to handle a private action', () => {
Expand All @@ -191,17 +193,24 @@ describe('Utils', () => {
})

it('warns if no reducers are passed to combineReducers', () => {
const spy = expect.spyOn(console, 'error')
const preSpy = console.error
const spy = jest.fn(() => {})
console.error = spy

const reducer = combineReducers({ })
reducer({ })
expect(spy.calls[0].arguments[0]).toMatch(
expect(spy.mock.calls[0][0]).toMatch(
/Store does not have a valid reducer/
)
spy.restore()
spy.mockClear()
console.error = preSpy
})

it('warns if input state does not match reducer shape', () => {
const spy = expect.spyOn(console, 'error')
const preSpy = console.error
const spy = jest.fn(() => {})
console.error = spy

const reducer = combineReducers({
foo(state = { bar: 1 }) {
return state
Expand All @@ -212,69 +221,75 @@ describe('Utils', () => {
})

reducer()
expect(spy.calls.length).toBe(0)
expect(spy.mock.calls.length).toBe(0)

reducer({ foo: { bar: 2 } })
expect(spy.calls.length).toBe(0)
expect(spy.mock.calls.length).toBe(0)

reducer({
foo: { bar: 2 },
baz: { qux: 4 }
})
expect(spy.calls.length).toBe(0)
expect(spy.mock.calls.length).toBe(0)

createStore(reducer, { bar: 2 })
expect(spy.calls[0].arguments[0]).toMatch(
expect(spy.mock.calls[0][0]).toMatch(
/Unexpected key "bar".*createStore.*instead: "foo", "baz"/
)

createStore(reducer, { bar: 2, qux: 4, thud: 5 })
expect(spy.calls[1].arguments[0]).toMatch(
expect(spy.mock.calls[1][0]).toMatch(
/Unexpected keys "qux", "thud".*createStore.*instead: "foo", "baz"/
)

createStore(reducer, 1)
expect(spy.calls[2].arguments[0]).toMatch(
expect(spy.mock.calls[2][0]).toMatch(
/createStore has unexpected type of "Number".*keys: "foo", "baz"/
)

reducer({ corge: 2 })
expect(spy.calls[3].arguments[0]).toMatch(
expect(spy.mock.calls[3][0]).toMatch(
/Unexpected key "corge".*reducer.*instead: "foo", "baz"/
)

reducer({ fred: 2, grault: 4 })
expect(spy.calls[4].arguments[0]).toMatch(
expect(spy.mock.calls[4][0]).toMatch(
/Unexpected keys "fred", "grault".*reducer.*instead: "foo", "baz"/
)

reducer(1)
expect(spy.calls[5].arguments[0]).toMatch(
expect(spy.mock.calls[5][0]).toMatch(
/reducer has unexpected type of "Number".*keys: "foo", "baz"/
)

spy.restore()
spy.mockClear()
console.error = preSpy
})

it('only warns for unexpected keys once', () => {
const spy = expect.spyOn(console, 'error')
const preSpy = console.error
const spy = jest.fn(() => {})
console.error = spy

const foo = (state = { foo: 1 }) => state
const bar = (state = { bar: 2 }) => state

expect(spy.calls.length).toBe(0)
expect(spy.mock.calls.length).toBe(0)
const reducer = combineReducers({ foo, bar })
const state = { foo: 1, bar: 2, qux: 3 }
reducer(state, {})
reducer(state, {})
reducer(state, {})
reducer(state, {})
expect(spy.calls.length).toBe(1)
expect(spy.mock.calls.length).toBe(1)
reducer({ ...state, baz: 5 }, {})
reducer({ ...state, baz: 5 }, {})
reducer({ ...state, baz: 5 }, {})
reducer({ ...state, baz: 5 }, {})
expect(spy.calls.length).toBe(2)
spy.restore()
expect(spy.mock.calls.length).toBe(2)

spy.mockClear()
console.error = preSpy
})
})
})
1 change: 0 additions & 1 deletion test/compose.spec.js
@@ -1,4 +1,3 @@
import expect from 'expect'
import { compose } from '../src'

describe('Utils', () => {
Expand Down

0 comments on commit 9af86bd

Please sign in to comment.