小ネタです。rubocopのバージョンアップを行ったら、新しいルールで怒られが発生しました。
C: [Correctable] Style/FetchEnvVar: Use ENV.fetch('FOO') or ENV.fetch('FOO', nil) instead of ENV['FOO'].
Correctableなので、bundle exec rubocop -A
で自動修正を行ったところ、ENV.fetch('FOO', nil)
になりました👍
これでテストを実行したところ、思わぬエラーが発生😵
環境変数をstubしているテストが落ちる
環境変数によって、とある項目をチェックするかどうかを切り替えている処理がありまして、そのテストのために以下のようにしていました。
context '環境変数BARに0が設定されている場合' do before do allow(ENV).to receive(:[]).and_call_original allow(ENV).to receive(:[]).with('BAR').and_return('0') end it 'チェックされないこと' do # テストケース end end
※この書き方は、以下の記事を参考にしています。
該当箇所のコードは、元々はこんな感じ。
if (ENV['BAR'] || '1') != '0' # チェックする end
これが、rubocopのAutoCorrectによって、こうなりました。(カッコが多かったため、手でも修正しています)
if ENV.fetch('BAR', '1') != '0' # チェックする end
これが全くstubされないように…😢
原因
これはstubの定義がENV['BAR']
の場合にしか対応していないためです。この変更に対応するには、ENV#fetch
の結果をstubしなければなりません。
解決方法
環境変数の参照の仕方のstubをfetch経由に変更します。
context '環境変数BARに0が設定されている場合' do before do allow(ENV).to receive(:fetch).and_call_original allow(ENV).to receive(:fetch).with('BAR', '1').and_return('0') end # 略 end
肝は、with('BAR', '1')
のところで、with('BAR')
だとstubされませんでした。きちんとデフォルト値まで渡さなければなりません。
まとめ
環境変数をちゃんとstubしているのに何故!?と5分くらい考えてしまいましたが、当然っちゃあ当然です😅 環境変数をfetch経由で受け取る修正をした際は、テストのstubも見直しましょう。