ActiveModel の errors.messages に入ってるエラーメッセージが、どの validation でひっかかったかテストで知りたい。
という思いがずっと前からあって下記エントリーのような対応をしていました。
Rails 触りはじめのエントリーでとても懐かしい。
それはいいとして expect(model.errors_on(:attribute)).to include("can't be blank")
みたいのは絶対に書きたくなかったのでおおむね満足していましたが、これレイルウェ~イから逸脱しすぎで全くよくないよねって思い至ったので、テスト時のみわかればいいやと思って model 側を触らないような対応をしました。
spec/rails_helper.rb
とかその他ふさわしい場所に追加。
module ActiveModel module Validations def has_error_on(attribute, error) self.valid? self.errors.messages[attribute].try(:include?, error) end end class Errors def generate_message(attribute, type = :invalid, options = {}) message_table[type] || type end def message_table { present: :absence, accepted: :acceptance, invalid: :format, not_a_number: :numericality, not_an_integer: :numericality, blank: :presence, } end end end
generate_message
は I18n
にわたして翻訳とかするんですがそれはテストではいらないので翻訳につかうキーをそのまま返すようにしました。message_table
メソッドは validator の名前と関係ないシンボルを渡す(なんでやねん)のがいくつかあったのでそれ戻す用です。
expect(model.has_error_on(:name, :presence)).to be_truthy
って感じの書けばテストできておおむね満足しました。