Redux Store (Action/Reducer) Testing
The 'Duck' modularization design pattern works vary nicely to compartmentalize the Redux store implementation for a given route (AKA: page). It is described here: Ducks: Redux Reducer Bundles.
A 'Duck' module file contains the following subset of crucial ingredients from the above diagram:
'Duck' module bubble parts.
Testing the 'Duck' Module
Basic Reducer Tests
These basic tests focus initially on bubble #4 above. In your local clone, at the bottom of the CompSciAphorismsMod.js file, you can see that the reducer is created using a helper function. Let's test this base reducer creation.
Edit Test
Open up your local clone of CompSciAphorismsMod.spec.js, the 'Duck' Module test file. This test file is using the Mocha testing framework using Mocha's Behavior Driven Development(BDD) interface that provides the describe()/it()
functions. Both take a text string as their 1st arg:
- 'describe' the group of tests and
- state each test's (
it()
) expectation of success.
To the 'Actions' test group, add this basic reducer test group:
describe('(Route/Module) CompSciAphorism/CompSciAphorismMod', () => {
describe('Actions', () => {
describe('Basic reduce tests', () => {
// 1.
it('Expected to be a function.', () => {
expect(aphorismReducer).to.be.a('function')
})
// 2.
it('Undefined state expected to initialize with `initialState`.', () => {
expect(aphorismReducer(undefined, { type: 'Idunno' }))
.to.eql(initialState)
})
// 3.
it('Passing an unknown action to reducer expected to return current state', () => {
let state = aphorismReducer(undefined, { type: 'Idunno' })
expect(state).to.eql(initialState)
state = aphorismReducer(state, {type: '@@@@@@@'})
expect(state).to.eql(initialState)
})
})
...
The test 'assertions' within each test are writen using the Chai assertion library leveraging it's BDD expect
interface.
These 3 tests will make certain:
- The reducer exists in the 'Duck' module as a function.
- running the reducer without passing in a state (
undefined
1st arg), results in the returned state to be deeply equal toinitialState
and - running the reducer with an action not recognized (there are none at this point), results in the returned state to be deeply equal to the current state.
Run the Tests
As noted in the prior chapter, we will use Karma to drive the Mocha tests against a set of browsers in parallel. In this example, the karam.conf.js is configured to test against both PhantomJS (the headless browser) and Firefox.
Run the tests using npm
leveraging the test
script provided within package.json:scripts.test
that is all setup to run karma
.1
✔ N tests completed
The final number of tests reported in the summary reflects the number of tests x browsers tested; in this case 5 tests x 2 browsers = '10 tests completed`.
$ npm test
...
START:
22 08 2016 08:54:14.816:INFO [karma]: Karma v1.1.2 server started at http://localhost:9876/
22 08 2016 08:54:14.819:INFO [launcher]: Launching browsers PhantomJS, Firefox with unlimited concurrency
...
(Component) CompSciAphorisms
✔ should exist
Container CompSciAphorismsContainer
✔ CompSciAphorisms & CompSciAphorismsContainer should exist
(Route/Module) CompSciAphorism/CompSciAphorismMod
Actions
✔ Expected to be a function.
✔ Undefined state expected to initialize with `initialState`.
✔ Passing an unknown action to reducer expected to return current state
Finished in 0.017 secs / 0.004 secs
SUMMARY:
✔ 10 tests completed
...
--- Footnotes ---
1. If your at all unfamiliar with how npm
can leverage the package.json:script
section to run builds, tests, start servers, etc., check out this excellent article by Anders Janmyr at Jayway:
Running scripts with npm