ActiveModel::Attributes APIの attribute
メソッドを使用して値のcastを行う場合に、shoulda-matchersが提供するマッチャを使ってバリデーションのテストを行おうとすると
意図しない挙動によってテストが落ちてしまう。
class SampleForm
include ActiveModel::Model
include ActiveModel::Attributes
attribute :user_id, :integer
validates :user_id, numericality: { greater_than_or_equal_to: 1 }, allow_nil: true
end
RSpec.describe SampleForm, type: :model do
it { is_expected.to validate_presence_of(:user_id).allow_nil }
end
presenceを検証するテストなので、 ""
を渡したら落ちる(invalid判定される)けど、 ""
が nil
にcastされていて落ちないからおかしいよ。って言ってる。
1) SampleForm should validate that :user_id cannot be empty/falsy
Failure/Error: it { is_expected.to validate_presence_of(:user_id) }
Expected SampleForm to validate that :user_id cannot
be empty/falsy, but this could not be proved.
After setting :user_id to ‹""› -- which was read back as ‹nil› -- the
matcher expected the SampleForm to be invalid, but
it was valid instead.
As indicated in the message above, :user_id seems to be changing
certain values as they are set, and this could have something to do
with why this test is failing. If you've overridden the writer method
for this attribute, then you may need to change it to make this test
pass, or do something else entirely.
# ./spec/forms/sample_form_spec.rb:9:in `block (2 levels) in <top (required)>'
Finished in 1.26 seconds (files took 3.19 seconds to load)
1 example, 1 failure