次から次へと発見しては忘れていくので、備忘録を作ることにしました。
また発見があったら追記していくつもりです。
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
let! の存在を忘れるな
忘れると、以下のようなダサい before節が書かれたりします。
let(:items){
list= create_list(:item, 10)
# いろいろセットアップしている
}
describe 'Item.some_aggregate_method' do
before { items } # let! にすればこの行がいらない
it { expect(Item.some_aggregate_method).to eq 10 }
end
let! で書けば、変数が呼ばれているかどうかに関わらず評価されるので、意味もなく変数を呼ばなくてよくなります。
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