1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Rails7】rspecにおける環境変数のスタブについて【object ENV】

Last updated at Posted at 2023-03-22

スタブするのにどの方法がよかったのか

筆者の場合、どのやり方でスタブできたのかをメモ代わりに残します。

各種詳細

MacBook Pro (13インチ, M1, 2020)を使用。

Railsプロジェクト
% ruby -v
ruby 3.2.1
% rails -v
Rails 7.0.4.2
Gemfile
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 のキーと値には文字列しかとることができません。

ヘルパーモジュールの作成

先程の英語の議論に戻ると、書き込まれた方がとても良さそうなサンプルコードを残されていましたので、私もそれをそのまま使いました。感謝 :pray:

設定ファイル内に記述
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() についてはこちら。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?