最近初めて、Rspecを触り始めて「あ、そうなんだ」って思ったことをまとめます。
調べたけどあまり出てこない部分のみ抽出してます。
Rspecの文法は他の記事を参考に。。。。。
勝手にDB構築してくれない
railsでは、下記のようにコードを書いてあれば問題なく、結果が出てきますよね。
#book.rb
belongs_to :author
#author.rb
has_many :books
#example_controller.rb
Author.new.books
#=> authorが持つbooks一覧
ですが、rspecではexample_controller.rbと同じことを書いても
nilで返ってきます。
どうもdbとメモリ間で同一化してくれないらしい。。。。
なので、
#spec内
Author.new.books = create_list(hogehoge)
みたいに定義してあげる必要があります。
define内で親モデルを呼び出してIDに入れられる
親モデルがあって子モデルがあり、子モデル側の外部キーに親のidを入れたいとき、
factorybot内において、
#books.rb
FactoryBot.define do
factory :book do
author
name "example"
price 100
end
end
authorと書いてあげれば、このdefine内でauthor_id 1みたいに定義しなくてもokです。
むしろ定義しちゃうとバグるみたい。。。。。
材料と結果を入れて仕様がわかりやすいようにする
これは概念というか、考え方の問題ですが、テストは動作確認だけでなく仕様を伝えるものでもあります。
ですので、テストを見たとき、この材料を渡すとこのような結果になるのね。。。ということが他の人にわかるように書いてあげないといけません。
例えば、bookのpriceの合計を出すメソッド(price_sum)を書いているとして。。。
#spec内
book1 = Book.new(price: 100)
book2 = Book.new(price: 200)
book3 = Book.new(price: 300)
price_sum
expect(hogehoge).to_eq 600
しっかりとbook1などの材料をspec内に書いてあげましょう。
普通にメソッドのみを書いてもテストは通りますが、
#spec内
price_sum
expect(hogehoge).to_eq 600
これだけ書いても何をテストしているのかさっぱりわかりません。。。。
しっかりとこの材料を与えてあげればこの返り値になるんだということがわかりやすいテストの方がいいですね。
テストは奥が深いですが、めっちゃ楽しいです!