スタブするのにどの方法がよかったのか
筆者の場合、どのやり方でスタブできたのかをメモ代わりに残します。
各種詳細
MacBook Pro (13インチ, M1, 2020)を使用。
% ruby -v
ruby 3.2.1
% rails -v
Rails 7.0.4.2
group :development, :test do
gem 'debug', platforms: %i[mri mingw x64_mingw]
gem 'factory_bot_rails'
gem 'pry-byebug'
gem 'pry-rails'
gem 'rspec-rails'
end
allowメソッドを使用した方法
rspecにはモック(依存コンポーネントの置き換え)を行うのにブロック渡しを行ってくれる allow()
メソッドが用意されているそうです。
ですがこちらの参考リンクでは、
英語になりますが、まずそもそもとして、Rails上において ENV
を参照(keyにしてもvalueにしても)する際に返す値はstringである。
それを allow(ENV).to receive(:[]).with('some_key').and_return('some_value')
によってスタブする時は、デフォルトのkey値として空のHashを返すことを期待している(投稿者いわく "you've stubbed it to return a blank hash as the default key")ため、あまり良いプラクティスではない、という議論がされています。
RubyのENVとは
ENV
はRails上に存在するものではなく、どうやらRubyの組み込みライブラリだそうです。
上記については、このページにもはっきりと記載があります。
環境変数を表すオブジェクト。Hash と同様のインターフェースを持ちます。ただし、Hash と異なり、ENV のキーと値には文字列しかとることができません。
ヘルパーモジュールの作成
先程の英語の議論に戻ると、書き込まれた方がとても良さそうなサンプルコードを残されていましたので、私もそれをそのまま使いました。感謝
module EnvHelpers
def with_env_vars(vars)
original = ENV.to_hash
vars.each { |k, v| ENV[k] = v }
begin
yield
ensure
ENV.replace(original)
end
end
end
RSpec.configure do |c|
c.include EnvHelpers
end
今回は環境変数の管理に dotenv-rails
を使用していますが、おそらくはプロジェクトを起動するタイミングで、gemがRubyのENVに仕込みを行っているのでしょうね。
上記ヘルパーメソッドは、その組み込みライブラリである ENV
を書き換えているのでしょう。
丁寧に調べたことで知見が積み重なったので嬉しいです。
ちなみに
そもそもとして allow()
は、私の場合ではスタブに成功しませんでした。RubyにしてもRailsにしても、以前のバージョンではrspec側の制御でどうにかなっていたのかもしれないです。
参考サイト
有名な記事かと思いますが、Githubリンクにしてもこちらに掲載されていました。
allow()
についてはこちら。