All Articles

6 min read • By Kyle Truong • Published 1 Oct 2017

Unit Testing React, Redux, Selectors, and Epics

How does unit testing work for front-end React-based applications in 2017?

Testing React Components

Components can be tested with snapshot testing. Tools like Jest (often combined with Enzyme) that offer this functionality take a ‘snapshot’ of what your component renders—everything from divs, attributes, classNames, props, and state—and saves it to a file, kind of like this:

Snapshot of a React component, generated by Jest

On subsequent test runs, Jest makes a new snapshot to compare with the old and breaks if the two don’t match, preventing any unintended changes to the rendering of your component. It’s not perfect as you can’t really do true test-driven-development where you make a failing test first then fix it, so you just have to trust that your initial snapshot is correct, but it’s really quick and easy:

import React from 'react';
import Link from '../Link.react';
import renderer from 'react-test-renderer';

it('renders correctly', () => {
  const tree = renderer.create(
    <Link page="">Facebook</Link>

Testing Redux Actions and Reducers Actions and Reducers are (should be) pure functions. Stuff goes in, stuff goes out. No side effects. Test it like a normal JavaScript function, something like this:

// reducer.js

export const initialState = {
  authenticated: false,
  authenticating: false,

export const loginReducer = (
  state = initialState,
) => {
  switch (action.type) {
      return {
        authenticating: false,
        authenticated: action.payload.authenticated
      return state;

// action.js
export const switchAuthenticatedFlag = status => {
  return {
    payload: {
      authenticated: status,

// reducer.test.js
describe('Login Reducers', () => {
  it('properly captures a dispatch to change authenticated state', () => {
    expect(loginReducer(initialState, switchAuthenticatedFlag(true)))
        authenticated: true,
        authenticating: false,

Testing Reselect Selectors

Selectors are pretty handy stuff. They untangle the mess that Redux state often ends up turning into and they allow you to abstract gnarly logic out from reducers so they stay clean and simple. Using the common createSelector function, it takes in some arguments and spits out some other function that takes in state and returns what you want selected from said state:

import { createSelector } from 'reselect'

const shopItemsSelector = state =>

const subtotalSelector = createSelector(
  items => items.reduce((acc, item) => acc + item.value, 0)

let exampleState = {
  shop: {
    taxPercent: 8,
    items: [
      { name: 'apple', value: 1.20 },
      { name: 'orange', value: 0.95 },

console.log(subtotalSelector(exampleState)) // 2.15

I guess I could mock the whole state, pass it through, and then check that it returns what I want it to, but that’s a lot of work.

All I really want to do is check the last function parameter, the function that actually performs the custom logic, and it just so happens that the object createSelector returns has a property, resultFunc, that returns the last passed-in function. Using this, we can test selectors like this:

// selectors.js
export const selectLogin = (state) => state.login;

export const selectAuthenticated = createSelector(
  (loginState) => loginState.authenticated

// selectors.test.js
import { type } from 'ramda';

import {
} from '../login.selectors';

describe('Login Selectors', () => {
  describe('selectAuthenticated', () => {
    it('should return login.authenticated as boolean', () => {
      mockParameters = {
        login: {
          authenticated: false,
          authenticating: false,
      const selected = selectAuthenticated.resultFunc(mockParameters.login);

Testing Epics

Epics are the core primitive of redux-observables, a RxJS-based middleware for Redux. I highly recommend giving observables and reactive programming a try because it makes dealing with asynchronous and/or event-based problems like user interactions, animations and timers, websockets, and AJAX calls a breeze.

Epics are functions that receive and output a stream of actions. The simplest way to test epics, in my experience, has been to just test the bare minimum of what an epic is supposed to do—actions in, actions out. Invoke your epic with an action, then test that the output action is what you expected.

Let’s say you got an epic that handles the flow for successful logins. Upon a successful login, you want to dispatch multiple actions: one to change routes, one to change authenticated state, and one to indicate the form submission has been completed:

// epic.js

export const loginSuccessEpic = (
) => action$
 .mergeMap(() => {
   return Observable.from([

In our testing, what we want to do is feed in an action of type LOGIN_TYPES.SUCCESS, and test that the output returns the three dispatched actions:

// epic.test.js

describe('loginSuccessEpic', () => {
   it('dispatches actions to change location, authenticated, and stopSubmit', () => {
     const action = ActionsObservable.of({
       payload: [{}, {}]
     loginSuccessEpic(action, {})
       .subscribe((outputActions) => {

If you want to learn more about this method, here’s a good article from @KevinSalter about testing epics:

Conclusion Testing doesn’t have to be a drag. It’s 2017 and we have the technology. Go write some tests and have fun.