redux-state-snapshot
v1.0.2
Published
Simple utility to help test your redux integration
Downloads
7
Maintainers
Readme
redux-state-snapshot
Simple utility to help test your redux integration
Motivation
Its common to test Redux in isolation, as its spearation of concerns lends well to unit tests, however testing the integration between ActionTypes, Actions and Reducers from an end user perspective is more challenging.
This tiny utility builds on top of the great work done with redux-mock-store
, and allows you to test your Redux actions (syncronously or asyncronously), offering your downstream components using Redux certainty, by taking a snapshot of your state after each action, to capture potential regressions.
Requirements
Install
yarn add redux-state-snapshot --dev
npm i redux-state-snapshot --dev
API
actionsToStateSnapshot(middleware, initialState)
Creates the store and returns function to execute Jest Snapshot
Parameters
middleware
[array]
An array of Redux middleware required to execute action
initialState
[any]
A default state to provide to redux Redux store, the same state being able to retrieved via .getState()
example
import { actionsToStateSnapshot } from 'redux-state-snapshot'
import thunk from 'redux-thunk'
const actionStateSnapshot = actionsToStateSnapshot([thunk], { foo: 'bar' })
Return
function(action, reducer)
action
[function]
Wrap your Redux action in a clossure (this will prevent the action from executing at runtime)
reducer
[function]
Pass your reducer to the function the same way you would combineReducers
example
import myAction from './my-action'
import myReducer from './my-reducer'
actionStateSnapshot(() => myAction(foo), reducer) // creates snapshot
Examples
import { actionsToStateSnapshot } from 'redux-state-snapshot'
import thunk from 'redux-thunk'
/* ACTION TYPES */
const ACTION_TYPE_TEST = 'ACTION_TYPE_TEST'
/* ACTIONS */
function starting() {
return {
type: `${ACTION_TYPE_TEST}_STARTING`,
}
}
function success(payload) {
return {
type: `${ACTION_TYPE_TEST}_SUCCESS`,
payload,
}
}
function failure(payload) {
return {
type: `${ACTION_TYPE_TEST}_FAILURE`,
payload,
}
}
function fetchDataSuccess() {
return dispatch => {
return Promise.resolve()
.then(dispatch(starting()))
.then(() => dispatch(success({ error: null, data: ['foo', 'bar'] })))
}
}
function fetchDataFailure() {
return dispatch => {
return Promise.resolve()
.then(dispatch(starting()))
.then(() => dispatch(failure({ error: 'Uh oh!', data: [] })))
}
}
function doAction(foo) {
return { type: ACTION_TYPE_TEST, foo }
}
/* REDUCER */
const reducer = (state = { data: [], error: null, loading: false }, action) => {
switch (action.type) {
case ACTION_TYPE_TEST:
return { ...state, foo: action.foo }
case `${ACTION_TYPE_TEST}_STARTING`:
return { ...state, loading: true }
case `${ACTION_TYPE_TEST}_FAILURE`:
case `${ACTION_TYPE_TEST}_SUCCESS`:
return { data: action.payload.data, error: action.payload.error, loading: false }
default:
return state
}
}
describe('GIVEN a user', () => {
describe('WHEN I want to test my async redux actions and state', () => {
describe('THEN I can use actionsToStateSnapshot for async actions', () => {
test('to snapshot on success', () => {
const actionStateSnapshot = actionsToStateSnapshot([thunk])
actionStateSnapshot(() => fetchDataSuccess(), reducer)
})
test('to snapshot on failure', () => {
const actionStateSnapshot = actionsToStateSnapshot([thunk])
actionStateSnapshot(() => fetchDataFailure(), reducer)
})
})
describe('AND I can use actionsToStateSnapshot for sync actions', () => {
test('to snapshot on success', () => {
const actionStateSnapshot = actionsToStateSnapshot()
actionStateSnapshot(() => doAction('bar'), reducer)
})
})
describe('AND I can use actionsToStateSnapshot with a default state', () => {
test('to snapshot on success', () => {
const initialState = { customData: true }
const actionStateSnapshot = actionsToStateSnapshot([], initialState)
actionStateSnapshot(() => doAction('bar'), reducer)
})
})
})
})