はじめに
rspecの書き方がいつも迷うのでまとめる。
まだまだ、随時編集を継続していく予定。
describe
の書き方
テストケースを説明するような書き方もあるけど、メソッド名だけをシンプルに書くほうが何をテストしてるのかがすぐにわかる。
逆に、何のテストを書いてないのかもすぐにわかる。
参考
https://shinkufencer.hateblo.jp/entry/2018/10/24/233000
インスタンスメソッドの場合
sample.rb
describe "#method_name" do
end
クラスメソッドの場合
sample.rb
describe ".method_name" do
end
コントローラー
リクエストスペックで書く。
ポイントは以下の通り。
ポイント
-
response.status
を必ず確認する - 画面に表示された内容や取得した情報が正しく表示されているかテストする場合、
response.body
に期待する内容が含まれているかを確認する
参考
https://qiita.com/t2kojima/items/ad7a8ade9e7a99fb4384
scopeの場合
sample.rb
describe "test" do
subject { SbGuaranteeExam.test }
context "含まれる場合" do
let!(:test) { build_stubbed :test }
it "検索される" do
is_expected.to include test
end
end
context "含まれない場合" do
let!(:test) { build_stubbed :test }
it "検索されない" do
is_expected.not_to include test
end
end
end
ポイント
-
describe
はスコープ名だけ書く。シャープやコンマは書かなくて良い - テストケースは、検索されるor検索されないの2ケースのみ設定でOK
- subjectを使う(まだ検討中、、、)
モデルのメソッドの場合
sample.rb
describe ".test_method" do
context "該当する場合" do
let(:test) { build_stubbed :test }
it "有効である" do
expect(test.test_method).to be_valid
end
end
end
ポイント
-
build
を使う
DBにアクセスせず、その属性があればテストができる時はcreate
でなくこちらを使う -
build_stubbed
を使う
build
は関連されたレコードを生成してしまう。関連するテーブルのレコードがいつようない場合はbuild_stubbed
を使う。
ただし、factoryの書き方によっては、効果がない時もある。((https://zenn.dev/yuji_developer/articles/8be2e10830c797#%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B35.-build-%E3%82%84-build_stubbed-%E3%81%A7db%E6%9B%B8%E3%81%8D%E8%BE%BC%E3%81%BF%E3%81%97%E3%81%A6%E3%81%84%E3%82%8Bfactory)
sample.rb
# 下記のような定義だと、build_stubbed使っても関連データが保存されてしまう
FactoryGirl.define do
factory :test do
hoge { create(:huga) }
end
end
# 下記の書き方なら、build_stubbedを使った時、関連データが保存されない
FactoryGirl.define do
factory :test do
association :hoge, factory: :huga
end
end
- subjectを使わない。(まだ検討中、、、)
デコレーターの場合
sample.rb
describe "#test_method" do
context "の場合" do
let!(:test) { build :test }
it "hogeが表示される" do
expect(test.test_method).to eq "hoge"
end
end
context "の場合" do
let!(:test) { build :test }
it "hugaが表示される" do
expect(test.test_method).to eq "huga"
end
end
end
ポイント
- 可能ならばbuild_stubbedやbildを使う
- subjectを使わない。(まだ検討中、、、)
モックを使い、メソッドが呼び出されたかテストする場合
インスタンスメソッドの場合
sample.rb
before {
test = Test.new
allow(test).to receive(:test_method)
}
# 呼び出されたかテスト
expect(test).to have_received(:test_method).once
# 呼び出されていないかテスト
expect(test).not_to have_received(:test_method).once
クラスメソッドの場合
sample.rb
before {
allow(Test).to receive(:test_method)
}
# 呼び出されたかテスト
expect(Test).to have_received(:test_method).once
# 呼び出されていないかテスト
expect(Test).not_to have_received(:test_method)
モックした時に特定の値を返すようにする
sample.rb
before {
allow(Test).to receive(:test_method).and_return(nil)
}
テストケースごとにテストデータの値を変更したい時
sample.rb
describe "#test_method" do
let(:test) { build :test, hoge: huga }
context "hugaがtrueの場合" do
let!(:huga) { true }
it "hogeが表示される" do
expect(test.test_method).to eq "hoge"
end
end
context "hugaがfalseの場合" do
let!(:huga) { false }
it "hugaが表示される" do
expect(test.test_method).to eq "huga"
end
end
end