npm package: @malfaitrobin/redux-test-utils
Description: Redux utilities
Author: Robin Malfait
Latest version: 0.0.1

## Test Utilities

### `testReducer`

> **NOTE:** This example uses [Jest](https://facebook.github.io/jest/). We also use a feature called [snapshot testing](https://facebook.github.io/jest/docs/en/snapshot-testing.html).

#### Standard example:

```js
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:

```js
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.

```js
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:

```js
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:

```js
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

```js
// selectors.js

export function getCurrentValue(state) {
  return state.applications.calculator.value;
}
```

```js
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();
  });
});
```