0.0.1 • Published 6 years ago

@malfaitrobin/redux-test-utils v0.0.1

Weekly downloads
-
License
MIT
Repository
github
Last release
6 years ago

Test Utilities

testReducer

NOTE: This example uses Jest. We also use a feature called snapshot testing.

Standard example:

import { testReducer } from "@malfaitrobin/redux-test-utils";

import reducer from "./reducer";
import * as actionCreators from "./actionCreators";

const calculator = testReducer(reducer);

describe("calculator", () => {
  it("should be able to calculate the universe", () => {
    const actions = [
      actionCreators.add(20),
      actionCreators.multiply(3),
      actionCreators.subtract(18)
    ];

    expect(calculator(actions)).toMatchSnapshot();
  });
});

The result of the snapshot will have the initial state Followed by the action followed by the state and so on. The snapshot will eventually look something like this:

Array [
  State {
    "value": 0,
  },
  Action {
    "payload": 20,
    "type": "ADD",
  },
  State {
    "value": 20,
  },
  Action {
    "payload": 3,
    "type": "MULTIPLY",
  },
  State {
    "value": 60,
  },
  Action {
    "payload": 18,
    "type": "SUBTRACT",
  },
  State {
    "value": 42,
  },
]

Overriding the current state before testing

Let's say that the default state from the reducer looks like { value: 0 }, but now you want to test the multiply function. Since multiplying by 0 is a no-op, we can override the "initial" value.

import { testReducer } from "@malfaitrobin/redux-test-utils";

import reducer from "./reducer";
import * as actionCreators from "./actionCreators";

const calculator = testReducer(reducer);

describe("calculator", () => {
  it("should be able to calculate the universe", () => {
    const actions = [actionCreators.multiply(3)];

    expect(
      calculator(actions, {
        value: 14
      })
    ).toMatchSnapshot();
  });
});

Normally the snapshot would have looked like this:

Array [
  State {
    "value": 0,
  },
  Action {
    "payload": 3,
    "type": "MULTIPLY",
  },
  State {
    "value": 0,
  },
]

But since we provided a default "initial" value, the snapshot looks like this:

Array [
  State {
    "value": 14,
  },
  Action {
    "payload": 3,
    "type": "MULTIPLY",
  },
  State {
    "value": 42,
  },
]

Using testReducer to also test the selectors

  • A reducer always operates on its part of the state
  • A selector retrieves information from the full state in the application
// selectors.js

export function getCurrentValue(state) {
  return state.applications.calculator.value;
}
import { testReducer } from "@malfaitrobin/redux-test-utils";

import reducer from "./reducer";
import * as actionCreators from "./actionCreators";
import * as selectors from "./selectors";

// We can mimic the "full" state, which will be used by selectors
const calculator = testReducer(reducer, state => {
  return {
    applications: {
      calculator: state
    }
  };
});

describe("calculator", () => {
  it("should be to retrieve the current value", () => {
    const actions = [
      actionCreators.add(20),
      actionCreators.multiply(3),
      actionCreators.subtract(18)
    ];

    // A final `state` object can be retrieved from the reducer
    const { state } = calculator(actions);

    // Now the selector can operate on the "full state"
    expect(selectors.getCurrentValue(state)).toMatchSnapshot();
  });
});