rspecで特定のカラムを更新するAPIのテストを書いていたところRubocopで以下のエラーが表示された。
Spec/AnyInstance: Avoid stubbing using allow_any_instance_of
以下Rubyのドキュメントによると、クラスのインスタンスをスタブ化するよりもインスタンスダブルを使ってね、とある
https://www.rubydoc.info/gems/rubocop-rspec/1.7.0/RuboCop/Cop/RSpec/AnyInstance
しかし、このリファレンスどおりやっても上手くいかなかったので
備忘録がてら対応を残しておく
修正前のソースコード ※簡素化してます
let(:user) { create(:user) }
it 'returns a 400 response' do
# patch処理を失敗させたい。rspecは成功するがRubocopで怒られる
allow_any_instance_of(User).to receive(:update).and_return(false)
patch "/api/v1/users/#{user.id}/ready"
expect(response).to have_http_status(:bad_request)
end
修正後のソースコード
let(:user) { create(:user) }
it 'returns a 400 response' do
# 以下に修正
allow(User).to receive(:find).and_return(user) // receive(:find)であることに注意
allow(user).to receive(:update).and_return(false)
patch "/api/v1/users/#{user.id}/ready"
expect(response).to have_http_status(:bad_request)
end
リファレンスではインスタンスダブルを作成して、クラスをnewしていたが
自分の場合は、すでに作成済みのデータだったため receive(:find)
とする必要があった
おわりに
直近3年くらいは新規サービスの構築ばかりしてきたものの、なるはやで世の中に出してニーズがあるか探り、都度方向修正という
スピード最優先のシステム開発が多く、テストを犠牲にしてきた分のつけというか、苦しさを今味わってるところです
ただ苦しいながらもテストが充実してきたおかげで開発やリファクタリングの安定感はすごいですね
単体テストの考え方って本を読んでても思いましたが徐々にテストファーストな開発にシフトしていきたいと感じる日々です
最終的には(?)テスト駆動開発など、最初にテストをすべて書ききらないにしても
テスト書くイメージをもちながら効率よく開発できるエンジニアになっていきたいですね