RSpec
Rails4

Rspec の小ネタ集

次から次へと発見しては忘れていくので、備忘録を作ることにしました。
また発見があったら追記していくつもりです。

letで定義したら、expect() でも expect{} でもいい感じ

変数としても、ブロックとしても評価できます、素晴らしい。
状態遷移のテストがとてもすっきり書けました。

context 'state1 -(action)-> state2' do
  let(:item){
    item= create(:item)
    item.action
  }

  # 遷移後の結果を確認する
  it { expect(item.aasm_state).to eq 'state2'}
  # 遷移の副作用(たとえば履歴保存とか)を確認する
  it { expect{ item }.to change{ ItemHistory.count }.by(1) }
end

Hash#with_indifferent_access はステキ

Faker とかのデータで undefined method hogehoge for nil:NilClass とか怒られる場合。
Hashのキーが Symbol なのに String でアクセスしようとしてるとかその逆とかありがちです。
Hash#with_indifferent_access と言っておくと、Symbol / String どちらでも見つけてくれるので、ハッピーです。

let(:user){
  auth= Faker::Omniauth.google.with_indifferent_access
  User.create_with_omniauth(auth)
}
it { expect(user).to be_valid }

テストとしては緩くする行為なので、見逃し原因にならないように注意は必要ですが。

ActiveRecord::Relation は配列と比較可能

scope のテストで良くあるというか、気づく前から使ってました。
match_array とかも問題なく使えます。

it 'self.sort' do
  list= create_list(:item, 3)
  list= [ list[1], list[2], list[0] ] # 期待値 <= これは配列
  expect(Item.sort).to eq list # expect の中は ActiveRecord::Relation だけど大丈夫
end

Factory で after_initialize が発火しない

build でも create でも、after_initialize は呼んでくれませんでした。
Factory の定義で明示的に呼べばOKです。

FactoryGirl.define do
  factory :item do
    after(:build){|item|
      item.send(:do_something)
    }
  end
end