2021-04-11 RSpec中の特定のtypeでmodule を include する / assert_select assertion
RSpec中の特定のtypeでmodule を include する
RSpec.configure do |config|
...
config.include(ControllerHelpers, :type => :controller)
...
end
Rails tips: テストから共通機能を切り出すリファクタリング(翻訳)|TechRacho(テックラッチョ)〜エンジニアの「?」を「!」に〜|BPS株式会社
こんな感じでtypeに応じてmoduleをincludeすることでそれぞれのtypeのみ有効なhelper methodを定義することができる。
# rails_helper.rb
RSpec.configure do |config|
...
# type: :request な spec のみでincludeされる
config.include(RequestSpecHelper, type: :request)
# type: :system な spec のみでincludeされる
config.include(SystemSpecHelper, type: :system)
# type: :view な spec のみでincludeされる
config.include(ViewSpecHelper, type: :view)
...
end
assert_select assertion
rspec で自動で generate されるview specにはassert_select
が使われていたので調べた。
assert_selectには2つの書式があります。
assert_select(セレクタ, [条件], [メッセージ])という書式は、セレクタで指定された要素が条件に一致することを主張します。セレクタにはCSSセレクタの式 (文字列) や代入値を持つ式を使えます。
assert_select(要素, セレクタ, [条件], [メッセージ]) は、選択されたすべての要素が条件に一致することを主張します。選択される要素は、element (Nokogiri::XML::Node or Nokogiri::XML::NodeSetのインスタンス) からその子孫要素までの範囲から選択されます。
ref. Rails テスティングガイド - Railsガイド
titleタグとその内部の文字列のチェック。
assert_select 'title', "Welcome to Rails Testing Guide"
ネストして書くことも可能。
assert_select 'ul.navigation' do
assert_select 'li.menu_item'
end
使ってみた
これをもとに書いたテストがこちら。
特定の form の内部の値が正しくセットされているかを検証している。
assert_select "form[action=?][method=?]", relationship_path, "post" do
assert_select "input[type=hidden][name=?][value=?]", "relationship[follower_id]", @login_user.id.to_s
assert_select "input[type=hidden][name=?][value=?]", "relationship[followed_id]", @user.id.to_s
assert_select "input[type=submit][value=?]", "Unfollow"
end