RSpecで独自matcherを作成してみよう
RSpecを使っていて、minitestならできるmatcher
が、RSpecにはないってことがあります。
例えば、統合テストでflash
の有無を確認する場合
minitest
asset flash.empty?
expect(page).to have_selector '.alert'
こんな感じになるかと思います。
flash
の有無という、観点で考えるなら、minitest
の方が伝わりやすいと思います。
原因は対応するmatcher
がないからだと思いました。
そこで、matcher
を作成してみましょう!
手順としては、matcherを定義するファイルを作成し、ファイルを読み込ませる設定にします。
まずは設定でmatcherを作成するファイルを読み込めるようにします。
spec/rails_helper.rb
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
コメントアウトになっていると思うので、コメントアウトをはずします。
次に、該当するフォルダとファイルを作成します。
mkdir spec/support touch spec/support/macther_helper.rb
spec/support/matcher_helper.rb
RSpec::Matchers.define :have_flash do |type| match do |page| expect(page).to have_selector("div.alert.alert-#{type}") end end
RSpec::Matchers.define
でmatcherを定義するという意味になります。
今回は、alertの状況により判断するようにしました。
こうすることで、次のようにできます。
expect(page).to have_flash 'success'
直感的にわかりやすくなったのではないでしょうか。
意外に簡単にmatcher自体は定義できるので、自分でカスタマイズするのもいいですね。