Method: Shoulda::Matchers::ActiveModel#validate_presence_of
- Defined in:
- lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb
#validate_presence_of(attr) ⇒ ValidatePresenceOfMatcher
The ‘validate_presence_of` matcher tests usage of the `validates_presence_of` validation.
class Robot
include ActiveModel::Model
attr_accessor :arms
validates_presence_of :arms
end
# RSpec
RSpec.describe Robot, type: :model do
it { should validate_presence_of(:arms) }
end
# Minitest (Shoulda)
class RobotTest < ActiveSupport::TestCase
should validate_presence_of(:arms)
end
#### Caveats
Under Rails 4 and greater, if your model ‘has_secure_password` and you are validating presence of the password using a record whose password has already been set prior to calling the matcher, you will be instructed to use a record whose password is empty instead.
For example, given this scenario:
class User < ActiveRecord::Base
has_secure_password validations: false
validates_presence_of :password
end
RSpec.describe User, type: :model do
subject { User.new(password: '123456') }
it { should validate_presence_of(:password) }
end
the above test will raise an error like this:
The validation failed because your User model declares
`has_secure_password`, and `validate_presence_of` was called on a
user which has `password` already set to a value. Please use a user
with an empty `password` instead.
This happens because ‘has_secure_password` itself overrides your model so that it is impossible to set `password` to nil. This means that it is impossible to test that setting `password` to nil places your model in an invalid state (which in turn means that the validation itself is unnecessary).
#### Qualifiers
##### allow_nil
Use ‘allow_nil` if your model has an optional attribute.
class Robot
include ActiveModel::Model
attr_accessor :nickname
validates_presence_of :nickname, allow_nil: true
end
# RSpec
RSpec.describe Robot, type: :model do
it { should validate_presence_of(:nickname).allow_nil }
end
# Minitest (Shoulda)
class RobotTest < ActiveSupport::TestCase
should validate_presence_of(:nickname).allow_nil
end
##### on
Use ‘on` if your validation applies only under a certain context.
class Robot
include ActiveModel::Model
attr_accessor :arms
validates_presence_of :arms, on: :create
end
# RSpec
RSpec.describe Robot, type: :model do
it { should validate_presence_of(:arms).on(:create) }
end
# Minitest (Shoulda)
class RobotTest < ActiveSupport::TestCase
should validate_presence_of(:arms).on(:create)
end
##### with_message
Use ‘with_message` if you are using a custom validation message.
class Robot
include ActiveModel::Model
attr_accessor :legs
validates_presence_of :legs, message: 'Robot has no legs'
end
# RSpec
RSpec.describe Robot, type: :model do
it do
should validate_presence_of(:legs).
('Robot has no legs')
end
end
# Minitest (Shoulda)
class RobotTest < ActiveSupport::TestCase
should validate_presence_of(:legs).
('Robot has no legs')
end
129 130 131 |
# File 'lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb', line 129 def validate_presence_of(attr) ValidatePresenceOfMatcher.new(attr) end |