s2s: reduxにおけるreducerのテスト。あなたがテストを書く必要はないかも知れない



![reducer-test-2.gif](https://qiita-image-store.s3.amazonaws.com/0/15319/03244ab6-fb1a-e8e6-0f56-94c9102f1e97.gif)



## なぜreducerのテストが重要か？
flow環境で型によって返るStateが担保されていたとしても、依然としてreducerのテストは重要です。
簡単な例をあげると、`INCREMENT`でcountが+1されるロジックがあるとき、number型であると保証されていたとしても、+1されているのか-1されているのか、はたまた+100000されているのかについては保証されていないからです。
そのロジックを担保するのがテストの役割です。

## reducerのテストの書き方
flow環境とそれ以外でテストの書き方が違います。
トラディショナルなテストだと`{type: ACTION}`の形式でテストを書くことが多いと思いますが、flow環境だとActionが型で担保されているためアクションクリエイターをそのまま実行して書きます。
トラディショナルな書き方でもいいですが、この方が補完も効くのでオススメします。

<img width="994" alt="スクリーンショット 2017-10-02 21.06.59.png" src="https://qiita-image-store.s3.amazonaws.com/0/15319/ee9e1c57-bd6a-5d39-881d-0130b5ba514f.png">

この書き方は、redux公式
のflowのサンプルにある書き方と同じなので、気になる人は確認するとよいと思います。

https://github.com/reactjs/redux/blob/c9ad6a40fe501919d359b910ea7c7f34532e11d9/examples/todos-flow/src/__tests__/reducers/todos.test.js

## テストケースの自動生成
そろそろ冒頭の動画の説明をします。
はっきり言って、テストを書くのは面倒です。
そして、テストを書き忘れる可能性についても考える必要があります。
だからこそ、**コードを書いた瞬間にテストがそこにある**のがベストです。
そして、これは**s2s**によって簡単に実現できます。
s2sについては以下の記事を読んでください。
**Source to Source**という概念とその使い方をまとめています。

[**さよならボイラープレート。s2sによる高速reduxアプリケーション構築**](https://qiita.com/akameco/items/e1489c6bbf3439ec6ca4)

GitHubはこちらです。

[**akameco/s2s**<br>Source to Source](https://github.com/akameco/s2s)

上記の記事を読んだ前提を話を進めると、`babel-plugin-s2s-reducer-test-case`をs2sに加えることによって動画のようにテストケースを生成できます。
`s2s.config.js`に以下を加えてください。

```js
    {
      test: /containers\/.+reducer.js/,
      input: 'reducer.test.js',
      output: 'reducer.test.js',
      plugin: ['s2s-reducer-test-case'],
    },
```

このプラグインは、switch/caseのアクションを取得し、`test('handle ACTION_NAME')`がすでにあれば生成をスキップし、なければ以下の形式のテストケースを生成します。INITIAL_STATEはreducerにinitialStateを書かれていればそれをINITIAL_STATEとして扱います。(v0.3から)

```js
test('handle ACTION_NAME', () => {
  expect(actions.ACTION_CREATER()).toEqual(INITIAL_STATE);
});
```

これによって、人間が書くのは、toEqualに与えるオブジェクトと引数だけになります。
これを使ったサンプルは以下にあるので、s2s.config.jsの書き方含めて参考にしてください。とはいえ、オプションなんてほとんどないんですが。

https://github.com/akameco/s2s-examples/tree/master/shopping-cart



![reducer-test-2.gif](https://qiita-image-store.s3.amazonaws.com/0/15319/03244ab6-fb1a-e8e6-0f56-94c9102f1e97.gif)


また、全てのs2sのプラグインはlernaとyarn workspaceによるモノレポで運用しています。イシューやプルリクお待ちしています。

https://github.com/akameco/s2s-plugins

## まとめ
flow環境におけるreducerのテスト、s2sによるreducerのテストケースの自動記述について書きました。
上記の通り、あなた**が**テストを書く必要はありません。**そこにテストはあります**。

なにかあれば、コメント欄、またはtwitterで議論しましょう。

<blockquote class="twitter-tweet" data-partner="tweetdeck"><p lang="ja" dir="ltr">s2sを使ったreducerのテストケースの生成。コードを書くとき、そこにテストはある <a href="https://t.co/FISlpWrpOe">https://t.co/FISlpWrpOe</a> <a href="https://t.co/8CNWHhOQwL">pic.twitter.com/8CNWHhOQwL</a></p>&mdash; 無職.js (@akameco) <a href="https://twitter.com/akameco/status/914804233395896320?ref_src=twsrc%5Etfw">October 2, 2017</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet" data-partner="tweetdeck"><p lang="ja" dir="ltr">reduxのreducerのテスト完全に思考停止しながらできるようになってきた<a href="https://t.co/9f7P6LmW2a">https://t.co/9f7P6LmW2a</a> <a href="https://t.co/tmuWXojY5C">pic.twitter.com/tmuWXojY5C</a></p>&mdash; 無職.js (@akameco) <a href="https://twitter.com/akameco/status/915127901648855040?ref_src=twsrc%5Etfw">October 3, 2017</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

## 変更履歴

### v0.2
initialStateを使わずnullを挿入する。v0.3でもinitialStateがなければ、nullを挿入する。

![reducer-test.gif](https://qiita-image-store.s3.amazonaws.com/0/15319/03b48bdd-ba7e-d5aa-ecf8-02e3d6c0707f.gif)