📑

RSpec でよく使う matcher まとめ

に公開

RSpec は matcher が多く迷いやすいので、現場で使用頻度の高いものを整理しました。

RSpec と matcher のざっくり復習

  • RSpec とは Ruby の代表的なテストフレームワーク。describe / context でシナリオを切り分け、it + expect で期待を書く。
  • matcher とは expect(actual).to matchermatcher 部分。actual が条件を満たしているかを判定する役目。

https://rspec.info/

頻出する matcher 一覧

値の比較・真偽チェック

matcher 使いどころ 使用例
eq 期待値と実際の値が同じ内容かを比較 expect(user.name).to eq('Yuta')
equal 同一オブジェクトかを比較 expect(actual).to equal(expected)
be_nil / be_truthy / be_falsey nil 判定や真偽値らしさをシンプルに書く expect(result).to be_truthy
be_present / be_blank Rails の present?, blank? を直接テスト expect(user.email).to be_present

コレクション/ハッシュの検証

matcher 使いどころ 使用例
include 配列や文字列に要素が含まれるか expect(tags).to include('ruby')
match_array 配列の要素が同じであれば順序は問わない expect(actual_ids).to match_array(expected_ids)
have_key ハッシュにキーが存在するか expect(params).to have_key(:user_id)

モデルのバリデーション・関連

matcher 使いどころ 使用例
be_valid / be_invalid モデルが保存できるかどうかをざっくり確認 expect(build(:user)).to be_valid
validate_presence_of, validate_numericality_of, belong_to Shoulda Matchers を使った宣言的テスト is_expected.to validate_presence_of(:title)

副作用・モックの検証

matcher 使いどころ 使用例
change ブロック実行前後で値が変わるか expect { create(:user) }.to change(User, :count).by(1)
raise_error ブロック実行で例外が発生するか expect { service.call }.to raise_error(StandardError)
receive / have_received メソッド呼び出しを検証(モック) expect(service).to receive(:call); subject.call

HTTP レスポンス・画面系(Capybara)

matcher 使いどころ 使用例
have_http_status レスポンスコードが期待通りか expect(response).to have_http_status(:ok)
redirect_to リダイレクト先を確認 expect(response).to redirect_to(dashboard_path)
have_current_path, have_content, have_selector システムテストで画面の状態をチェック expect(page).to have_content('ようこそ')

まとめ

  1. 値比較・真偽: eq, be_nil, be_truthy, be_present, be_blank
  2. 配列・ハッシュ: include, match_array, have_key
  3. バリデーション: be_valid, be_invalid, validate_presence_of, validate_numericality_of, belong_to
  4. 副作用: change, raise_error, receive, have_received
  5. HTTP/画面: have_http_status, redirect_to, have_content, have_current_path

まずはこの辺りのセットを押さえておけば、通常のテストでは困らない印象です。
細かい matcher は AI や公式ドキュメントで都度補完したいと思います。

Discussion