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:

  1. 'describe' the group of tests and
  2. 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:

  1. The reducer exists in the 'Duck' module as a function.
  2. running the reducer without passing in a state (undefined 1st arg), results in the returned state to be deeply equal to initialState and
  3. 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

… Incomplete …

Service tests

Add Postman button to run these calls

E.g.: Run in Postman

Will embed this (not ready!):