テストのロジックは同じだけど、入力値とそれに対する結果が異なるみたいなテストをシンプルにかけるrspec-parametrizedというgemがあります。

存在は知ってたけどしばらく使ってなかったんですが、試しに入れてみたらすごくシンプルに使えるし、パラメータ変えてテストできるようなメソッドにしようみたいな意識がより働いてコードに良い影響もありそうな気がしています。

wherewith_themを使ってテストを書いていきます。↓はREADMEのサンプルの一部でして、whereに値の組み合わせ、with_themにテストコード自体を書く使い方をします。

 1describe "plus" do
 2  where(:a, :b, :answer) do
 3    [
 4      [1 , 2 , 3],
 5      [5 , 8 , 13],
 6      [0 , 0 , 0]
 7    ]
 8  end
 9
10  with_them do
11    it "should do additions" do
12      expect(a + b).to eq answer
13    end
14  end
15end

↑の例だと、a,b,answerという3つのパラメータにセットする値をArrayのArrayで渡しています。すると、with_themに書いたテストが以下の3つの条件で実行されるというわけです。

  • a=1, b=2, answer=3
  • a=5, b=8, answer=13
  • a=0, b=0, answer=0

whereの書き方には↑のようなArrayのパターンやHashを使ったパターン、さらに独自のテーブル記法を使うこともできます。

1using RSpec::Parameterized::TableSyntax
2
3where(:a, :b, :answer) do
4  1 | 2 | 3
5  5 | 8 | 13
6  0 | 0 | 0
7end

直感的っちゃ直感的ですが、using RSpec::Parameterized::TableSyntaxしないと使えなくてひと手間かかるとも言えるので、この辺は好みですね。

ということで、パラメータのみが変わるテストはrspec-parameterizedでDRYにして、入出力の条件にフォーカスして必要なテストをかけるようにしましょー。