describeとRSpec.describeはどちらの書き方が良いのか

この記事は「ESM Advent Calendar 2021」の3日目の記事です。

adventar.org

はじめに

Railsアプリケーションをの開発でRSpecを使ってテストを書くことが多いです。私はRSpecを書くときに、トップレベルの階層の describe をdescribe ではなく RSpec.describe でいつも書いています。

トップレベルに describe を書くパターン。

descirbe User, type: :model do
  descirbe "foo" do
    # ...
  end
end

トップレベルに RSpec.describe を書くパターン。

RSpec.descirbe User, type: :model do
  descirbe "foo" do
    # ...
  end
end

どちらの書き方でも動作します。

ちなみに、rspec/rspec-core のREADMEでは RSpec.describe の書き方で統一されています。

github.com

どちらの書き方が推奨されているか気になったので、調べてみることにしました。

調べたこと

stack overflowでまさにこれの質問を見つけました。

stackoverflow.com

回答によるとRSpec バージョン3からは describe の書き方制限するオプションが新たに加えられたそうです。

relishapp.com

後方互換性を維持するためconfig.expose_dsl_globally がデフォルトで true になっており、 describeRSpec.describe も書くことができるようにはなっています。

ただし、expose_dsl_globally = false を設定すると describe だと "undefined method 'describe'" にすることができます。

この辺りのバーション3系のアップデートを日本語でまとめている記事もありました。

nilp.hatenablog.com

また generator が作るspecファイルも RSpec.describe の書き方に書き換えられている。

github.com

まとめ

調査から分かったこと

  • バージョン3から describe の書き方を禁止するオプションが追加された。
  • describe はmainをモンキーパッチしているためあまりよくない
  • RSpec側でもREADMEなどが RSpec.describe に書き換えられて、主流になっている模様

追記

expose_dsl_globally = false とする代わりに、

RSpec.configure { |c| c.disable_monkey_patching! }

とすることでも describe の書き方を禁止することができます。

expose_dsl_globally = false よりも強力にモンキーパッチを禁止することができるため、私もあまり使ったことがなかった shouldstub といったメソッドも禁止にできるようです。

relishapp.com