もふもふ技術部

RSpecをリファクタリングしたくなってきたのでまずはsubjectを使ってみよう


RSpecは非常に優秀なテストフレームワークなので毎度お世話になっております。

テストをガンガン書いて質を高めて行くのは良いのですが、なんとなくそれをやり続けていると、じわりじわりと壊れやすいテストが邪魔してくるようになります。

なのでRSpecのテストコードを柔軟にしていくためにリファクタリングしたいなーと思った次第。まずはsubjectを切り出す方面でやってみます。

こんなコード

下記のようなDBテーブルを準備しました。

Migrationファイル

FactoryGirl使います(詳細は割愛)。

Item#find_over_priceというメソッドのテストを書きます。このメソッドは引数に与えられた値以上のpriceを持つレコードを返すメソッドです。

テストパターンとしては、

  • 500円以上のレコードが存在する場合は抽出される
  • 500円以上のレコードが存在しない場合は抽出されない

としました。するとこんな感じのテストコードになります。

こんな感じの実装でグリーンになります。

「items = Item.find_over_price(500)」が二度出現していて冗長ですね。二度で済めばいいですが、こういうテストコードを書くと、テストケースを追加するときにコピペしちゃったりして同じコードが増殖しがちです。

そこで、下記のように subject を使って共通のテスト対象を切り出します。

このようにするとsubjectのブロックで実行された結果が、expectのレシーバになります。ちなみにこの例では、subjectに別名(items)をつけています。

減った行数はたった1行ですが、it内のコードが少なくなるのはテストの意図が明確になるので良いかと思います。また、subjectという表現でテスト対象のオブジェクトが明確化されるので読みやすくなるんではないかと。

ちょっと今回例が悪かったかな?的確な例を作るのが困難だったもんで。

The following two tabs change content below.
原田 敦

原田 敦

日本CAWのエンジニア。もふもふ部の部長。得意分野はRuby on Railsを使った小規模WEBアプリケーションを高速で開発すること。週末の楽しみは一人お菓子パーティー。三度の飯より小動物をもふもふするのが好きです。