はじめに
仕事で、フラグとなる情報の値で表示内容を変える処理が含まれるViewに対するRSpecを書く必要が出ててきて、調べたついでにまとめてみました
少し前に、RSpec使ってERBに対するspecをどう書くか?を書いたのですが、それよりは少し実用的な内容になったかなと思ってます。
環境
- Mac OS X 10.8.5
- Ruby 2.2.0
- rbenv利用してインストールしてます
- rails 4.2.0
- rspec 3.1.0
- haml (4.0.6)
- haml-rails (0.8.2)
想定してるアプリ
レストラン情報を管理できるWebサイトを想定してます。
- そのお店の食べログの情報を管理できるようにModelを定義してる
- この値に応じて特定のUIの要素を表示したい
- お店の食べログサイトの情報をDB上に格納してる場合にはリンク先となるボタンを表示
レストランを管理するモデルを作成する
まずは以下の様な流れでレストランを管理するRestaurantモデルを作成します
generator&migrate
./bin/rails g model name:string tabelog_url:string
./bin/rake db:create
./bin/rake db:migrate
出来上がるRestaurantモデル
app/models/restaurant.rbは以下の様な感じになるかと思います。
class Restaurant < ActiveRecord::Base
end
restaurantsテーブルはこんな感じです
| Field | Type | Null | Key | Default | Extra |
+----------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| tabelog_url | varchar(255) | YES | | NULL | |
| name | varchar(255) | NO | | NULL | |
テストデータを定義してします
後述するようにRSpec使ってテストをしていくので先にFactoryGirl使ってテストデータも設定してしまいます
FactoryGirlの中身
spec/factories/restaurants.rbを作って以下のように記述しました。
FactoryGirl.define do
factory :restaurant do
sequence(:tabelog_url) { |n| "restaurant_tabelog_url#{n}" }
sequence(:name) { |n| "restaurant_name#{n}" }
end
end
specをまずは書く
フラグとなるような情報を参照して
- その情報が存在してる場合にはそのページを表示するためのボタンが1つ表示される
- その情報が存在してない場合にはそのページを表示するためのボタンが表示されない
ということをテストしたいので、specを書きます。
※ 情報が存在してるケースとそうでないケースの切り分けでcontextを使ってるけどはたしてこういう書き方が適切か自信がない・・
作成したspec
describe 'restaurants/show.html.haml' do
context 'valid data' do
let(:restaurant) { build :restaurant }
before do
assign(:restaurant, restaurant)
end
it 'should render _basic_info.html.haml' do
render
expect(rendered).to have_css(".tabelog_button", count: 1)
end
end
context 'no tabelog_url' do
let(:no_info_button_restaurant) { build(:restaurant, tabelog_url: nil) }
before do
assign(:restaurant, no_info_button_restaurant)
end
it "should render restaurants/show.html.haml without information button" do
render
expect(rendered).to have_css(".tabelog_button", count: 0)
end
end
end
上記のspecパスするように画面を実装する
まだこの段階では実装してないのでテストしてもパスしないので、なので、上記パスするように実際の画面を実装します。
実装する画面のHaml
app/views/restaurants/show.html.hamlを作って以下を記述します。
- if restaurant.try(:tabelog_url)
%button.tabelog_button 食べログ
if..present?でも良かったけどtryの方がスッキリ書けた
この記事を書くまで、tryメソッドを知らずif restaurant.tabelog_url.present?みたいな感じで書こうと思い、もう少しスマートに書けそうな気がして調べたらRubyOnRailsでこんなコードを書いてたら今すぐリファクタリングして1行にまとめちゃおうぜ!small tips!を見つけてtryを知りました!
最後に
こういうViewに対するRSpecをちょっとづつですが書けるようになってきてRailsでの開発がより楽しくなってきました(^^)