ActiveRecordのtakeメソッドがテスタブルだった
Railsにおいてある特定個数の要素がほしいときに以下のようなコードをよく書くと思います。
Article.most_recently.limit(5)
ただこのように書いてしまうと、 limit
はrailsのメソッドのためテストコードが書きにくくなってしまいます。具体的な例を上げると、これをコントローラーのユニットテストをしようとしたときにスタブにするコードが以下のようなものになります。
let(:most_recently) { double('most_recently', limit: [double('article')]) } before do allow(Article).to recevive(:most_recently) { most_recently } end
most_recently
メソッドの出力として、limit
メソッドを持つスタブを登録して、その limit
で配列を返しています。ただ自分の場合は most_recently
の時点で pure rubyの配列として扱い出したいので limit
なんてものは介したくありません。
そこでrailsって take
メソッドもあったよなーと思い実行してみるとちゃんと limit
もつけてくれてました。
Article.most_recently.take(5) Article.most_recently.limit(5).to_a
railsの take
のソースコードを見ると1行目のコードを実行すると、2行目と同じ処理をしていました。
take
を引数付きで呼ぶと、その引数で limit
をつけてSQLを発行した結果を返してくれています。これを使えば先程のテストコードは以下のようにできます。
before do allow(Article).to recevive(:most_recently) { [double('article')] } end
limit
をpure rubyにもある take
に置き直したことで、スタブにしなくて良くなりました。個人的にはすごく嬉しい発見です。
ただ to_a
していることから分かる通り、返り値が ActiveRecord_Relation
ではなく Array
なのでそこには注意してください。