RSpec 2.4/2.6でヘルパーのテストをしていてはまった話
rails new hello worldとしてRSpecの設定をしただけの状態で以下を作成する。まずテストのコード:
describe HelloHelper do describe '#each_productは' do it '@productに値を設定してyieldすること' do assign(:products, [ mock_model('Product', :price => 100), ]) output = helper.each_product do helper.product_price end output.should == '100' end end end次にヘルパーのコード:
module HelloHelper def each_product(&block) buf = '' @products.each do |product| @product = product buf << capture(&block) end buf end def product_price @product.price.to_s end endこれは通る。 この状態からしばらくして他のテストを書いていくうちに、こんなのを加えたとする。
describe HelloHelper do before do assign(:product, mock_model('Product', :price => 1)) end ...
ありがちな書き方だと思うのだけど、どうだろう。そしてこれの変化によりテストを走らせると結果がこのようになる。
F Failures: 1) HelloHelper#each_productは @productに値を設定してyieldすること Failure/Error: output.should == '100' expected: "100" got: "1" (using ==) # ./spec/helpers/hello_helper_spec.rb:28 Finished in 0.02024 seconds 1 example, 1 failure Failed examples: rspec ./spec/helpers/hello_helper_spec.rb:20 # HelloHelper#each_productは @productに値を設定してyieldすること
先の追加のコードが、こういうものだったら影響はない:
before do assign(:_product, mock_model('Product', :price => 1)) end
だが、よりやっかいなことに、こういうコードだと影響を受ける:
before do @product = assign(:foo, mock_model('Product', :price => 1)) end
テストの結果はやはりこう:
F Failures: 1) HelloHelper#each_productは @productに値を設定してyieldすること Failure/Error: output.should == '100' expected: "100" got: "1" (using ==) # ./spec/helpers/hello_helper_spec.rb:29 Finished in 0.02026 seconds 1 example, 1 failure Failed examples: rspec ./spec/helpers/hello_helper_spec.rb:21 # HelloHelper#each_productは @productに値を設定してyieldすること