module Shoulda::Matchers::ActiveModel
Public Instance Methods
The `allow_mass_assignment_of` matcher tests usage of Rails 3's `attr_accessible` and `attr_protected` macros, asserting that an attribute in your model is contained in either the whitelist or blacklist and thus can or cannot be set via mass assignment.
class Post include ActiveModel::Model include ActiveModel::MassAssignmentSecurity attr_accessor :title attr_accessible :title end class User include ActiveModel::Model include ActiveModel::MassAssignmentSecurity attr_accessor :encrypted_password attr_protected :encrypted_password end # RSpec describe Post do it { should allow_mass_assignment_of(:title) } end describe User do it { should_not allow_mass_assignment_of(:encrypted_password) } end # Test::Unit class PostTest < ActiveSupport::TestCase should allow_mass_assignment_of(:title) end class UserTest < ActiveSupport::TestCase should_not allow_mass_assignment_of(:encrypted_password) end
#### Optional qualifiers
##### as
Use `as` if your mass-assignment rules apply only under a certain role *(Rails >= 3.1 only)*.
class Post include ActiveModel::Model include ActiveModel::MassAssignmentSecurity attr_accessor :title attr_accessible :title, as: :admin end # RSpec describe Post do it { should allow_mass_assignment_of(:title).as(:admin) } end # Test::Unit class PostTest < ActiveSupport::TestCase should allow_mass_assignment_of(:title).as(:admin) end
@return [AllowMassAssignmentOfMatcher]
# File lib/shoulda/matchers/active_model/allow_mass_assignment_of_matcher.rb, line 70 def allow_mass_assignment_of(value) AllowMassAssignmentOfMatcher.new(value) end
The `allow_value` matcher is used to test that an attribute of a model can or cannot be set to a particular value or values. It is most commonly used in conjunction with the `validates_format_of` validation.
#### should
In the positive form, `allow_value` asserts that an attribute can be set to one or more values, succeeding if none of the values cause the record to be invalid:
class UserProfile include ActiveModel::Model attr_accessor :website_url validates_format_of :website_url, with: URI.regexp end # RSpec describe UserProfile do it do should allow_value('http://foo.com', 'http://bar.com/baz'). for(:website_url) end end # Test::Unit class UserProfileTest < ActiveSupport::TestCase should allow_value('http://foo.com', 'http://bar.com/baz'). for(:website_url) end
#### should_not
In the negative form, `allow_value` asserts that an attribute cannot be set to one or more values, succeeding if the first value causes the record to be invalid.
**This can be surprising** so in this case if you need to check that all of the values are invalid, use separate assertions:
class UserProfile include ActiveModel::Model attr_accessor :website_url validates_format_of :website_url, with: URI.regexp end describe UserProfile do # One assertion: 'buz' and 'bar' will not be tested it { should_not allow_value('fiz', 'buz', 'bar').for(:website_url) } # Three assertions, all tested separately it { should_not allow_value('fiz').for(:website_url) } it { should_not allow_value('buz').for(:website_url) } it { should_not allow_value('bar').for(:website_url) } end
#### Qualifiers
##### on
Use `on` if your validation applies only under a certain context.
class UserProfile include ActiveModel::Model attr_accessor :birthday_as_string validates_format_of :birthday_as_string, with: /^(\d+)-(\d+)-(\d+)$/, on: :create end # RSpec describe UserProfile do it do should allow_value('2013-01-01'). for(:birthday_as_string). on(:create) end end # Test::Unit class UserProfileTest < ActiveSupport::TestCase should allow_value('2013-01-01'). for(:birthday_as_string). on(:create) end
##### with_message
Use `with_message` if you are using a custom validation message.
class UserProfile include ActiveModel::Model attr_accessor :state validates_format_of :state, with: /^(open|closed)$/, message: 'State must be open or closed' end # RSpec describe UserProfile do it do should allow_value('open', 'closed'). for(:state). with_message('State must be open or closed') end end # Test::Unit class UserProfileTest < ActiveSupport::TestCase should allow_value('open', 'closed'). for(:state). with_message('State must be open or closed') end
Use `with_message` with the `:against` option if the attribute the validation message is stored under is different from the attribute being validated.
class UserProfile include ActiveModel::Model attr_accessor :sports_team validate :sports_team_must_be_valid private def sports_team_must_be_valid if sports_team !~ /^(Broncos|Titans)$/i self.errors.add :chosen_sports_team, 'Must be either a Broncos fan or a Titans fan' end end end # RSpec describe UserProfile do it do should allow_value('Broncos', 'Titans'). for(:sports_team). with_message('Must be either a Broncos or Titans fan', against: :chosen_sports_team ) end end # Test::Unit class UserProfileTest < ActiveSupport::TestCase should allow_value('Broncos', 'Titans'). for(:sports_team). with_message('Must be either a Broncos or Titans fan', against: :chosen_sports_team ) end
@return [AllowValueMatcher]
# File lib/shoulda/matchers/active_model/allow_value_matcher.rb, line 163 def allow_value(*values) if values.empty? raise ArgumentError, 'need at least one argument' else AllowValueMatcher.new(*values) end end
@deprecated Use {#validate_exclusion_of} instead. @return [ValidateExclusionOfMatcher]
# File lib/shoulda/matchers/active_model/validate_exclusion_of_matcher.rb, line 94 def ensure_exclusion_of(attr) Shoulda::Matchers.warn_about_deprecated_method( :ensure_exclusion_of, :validate_exclusion_of ) validate_exclusion_of(attr) end
@deprecated Use {#validate_inclusion_of} instead. @return [ValidateInclusionOfMatcher]
# File lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb, line 239 def ensure_inclusion_of(attr) Shoulda::Matchers.warn_about_deprecated_method( :ensure_inclusion_of, :validate_inclusion_of ) validate_inclusion_of(attr) end
@deprecated Use {#validate_length_of} instead. @return [ValidateLengthOfMatcher]
# File lib/shoulda/matchers/active_model/validate_length_of_matcher.rb, line 202 def ensure_length_of(attr) Shoulda::Matchers.warn_about_deprecated_method( :ensure_length_of, :validate_length_of ) validate_length_of(attr) end
The `have_secure_password` matcher tests usage of the `has_secure_password` macro.
#### Example
class User include ActiveModel::Model include ActiveModel::SecurePassword attr_accessor :password has_secure_password end # RSpec describe User do it { should have_secure_password } end # Test::Unit class UserTest < ActiveSupport::TestCase should have_secure_password end
@return [HaveSecurePasswordMatcher]
# File lib/shoulda/matchers/active_model/have_secure_password_matcher.rb, line 29 def have_secure_password HaveSecurePasswordMatcher.new end
The `validate_absence_of` matcher tests the usage of the `validates_absence_of` validation.
class Artillery include ActiveModel::Model attr_accessor :arms validates_absence_of :arms end # RSpec describe Artillery do it { should validate_absence_of(:arms) } end # Test::Unit class ArtilleryTest < ActiveSupport::TestCase should validate_absence_of(:arms) end
#### Qualifiers
##### with_message
Use `with_message` if you are using a custom validation message.
class Artillery include ActiveModel::Model attr_accessor :arms validates_absence_of :arms, message: "We're fresh outta arms here, soldier!" end # RSpec describe Artillery do it do should validate_absence_of(:arms). with_message("We're fresh outta arms here, soldier!") end end # Test::Unit class ArtilleryTest < ActiveSupport::TestCase should validate_absence_of(:arms). with_message("We're fresh outta arms here, soldier!") end
@return [ValidateAbsenceOfMatcher}
# File lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb, line 54 def validate_absence_of(attr) ValidateAbsenceOfMatcher.new(attr) end
The `validate_acceptance_of` matcher tests usage of the `validates_acceptance_of` validation.
class Registration include ActiveModel::Model attr_accessor :eula validates_acceptance_of :eula end # RSpec describe Registration do it { should validate_acceptance_of(:eula) } end # Test::Unit class RegistrationTest < ActiveSupport::TestCase should validate_acceptance_of(:eula) end
#### Qualifiers
##### with_message
Use `with_message` if you are using a custom validation message.
class Registration include ActiveModel::Model attr_accessor :terms_of_service validates_acceptance_of :terms_of_service, message: 'You must accept the terms of service' end # RSpec describe Registration do it do should validate_acceptance_of(:terms_of_service). with_message('You must accept the terms of service') end end # Test::Unit class RegistrationTest < ActiveSupport::TestCase should validate_acceptance_of(:terms_of_service). with_message('You must accept the terms of service') end
@return [ValidateAcceptanceOfMatcher]
# File lib/shoulda/matchers/active_model/validate_acceptance_of_matcher.rb, line 54 def validate_acceptance_of(attr) ValidateAcceptanceOfMatcher.new(attr) end
The `validate_confirmation_of` matcher tests usage of the `validates_confirmation_of` validation.
class User include ActiveModel::Model attr_accessor :email validates_confirmation_of :email end # RSpec describe User do it { should validate_confirmation_of(:email) } end # Test::Unit class UserTest < ActiveSupport::TestCase should validate_confirmation_of(:email) end
#### Qualifiers
##### with_message
Use `with_message` if you are using a custom validation message.
class User include ActiveModel::Model attr_accessor :password validates_confirmation_of :password, message: 'Please re-enter your password' end # RSpec describe User do it do should validate_confirmation_of(:password). with_message('Please re-enter your password') end end # Test::Unit class UserTest < ActiveSupport::TestCase should validate_confirmation_of(:password). with_message('Please re-enter your password') end
@return [ValidateConfirmationOfMatcher]
# File lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb, line 54 def validate_confirmation_of(attr) ValidateConfirmationOfMatcher.new(attr) end
The `validate_exclusion_of` matcher tests usage of the `validates_exclusion_of` validation, asserting that an attribute cannot take a blacklist of values, and inversely, can take values outside of this list.
If your blacklist is an array of values, use `in_array`:
class Game include ActiveModel::Model attr_accessor :supported_os validates_exclusion_of :supported_os, in: ['Mac', 'Linux'] end # RSpec describe Game do it do should validate_exclusion_of(:supported_os). in_array(['Mac', 'Linux']) end end # Test::Unit class GameTest < ActiveSupport::TestCase should validate_exclusion_of(:supported_os). in_array(['Mac', 'Linux']) end
If your blacklist is a range of values, use `in_range`:
class Game include ActiveModel::Model attr_accessor :supported_os validates_exclusion_of :supported_os, in: ['Mac', 'Linux'] end # RSpec describe Game do it do should validate_exclusion_of(:floors_with_enemies). in_range(5..8) end end # Test::Unit class GameTest < ActiveSupport::TestCase should validate_exclusion_of(:floors_with_enemies). in_range(5..8) end
#### Qualifiers
##### with_message
Use `with_message` if you are using a custom validation message.
class Game include ActiveModel::Model attr_accessor :weapon validates_exclusion_of :weapon, in: ['pistol', 'paintball gun', 'stick'], message: 'You chose a puny weapon' end # RSpec describe Game do it do should validate_exclusion_of(:weapon). in_array(['pistol', 'paintball gun', 'stick']). with_message('You chose a puny weapon') end end # Test::Unit class GameTest < ActiveSupport::TestCase should validate_exclusion_of(:weapon). in_array(['pistol', 'paintball gun', 'stick']). with_message('You chose a puny weapon') end
@return [ValidateExclusionOfMatcher]
# File lib/shoulda/matchers/active_model/validate_exclusion_of_matcher.rb, line 88 def validate_exclusion_of(attr) ValidateExclusionOfMatcher.new(attr) end
The `validate_inclusion_of` matcher tests usage of the `validates_inclusion_of` validation, asserting that an attribute can take a whitelist of values and cannot take values outside of this list.
If your whitelist is an array of values, use `in_array`:
class Issue include ActiveModel::Model attr_accessor :state validates_inclusion_of :state, in: %w(open resolved unresolved) end # RSpec describe Issue do it do should validate_inclusion_of(:state). in_array(%w(open resolved unresolved)) end end # Test::Unit class IssueTest < ActiveSupport::TestCase should validate_inclusion_of(:state). in_array(%w(open resolved unresolved)) end
If your whitelist is a range of values, use `in_range`:
class Issue include ActiveModel::Model attr_accessor :priority validates_inclusion_of :priority, in: 1..5 end # RSpec describe Issue do it { should validate_inclusion_of(:state).in_range(1..5) } end # Test::Unit class IssueTest < ActiveSupport::TestCase should validate_inclusion_of(:state).in_range(1..5) end
#### Caveats
We discourage using `validate_inclusion_of` with boolean columns. In fact, there is never a case where a boolean column will be anything but true, false, or nil, as ActiveRecord will type-cast an incoming value to one of these three values. That means there isn't any way we can refute this logic in a test. Hence, this will produce a warning:
it { should validate_inclusion_of(:imported).in_array([true, false]) }
The only case where `validate_inclusion_of` could be appropriate is for ensuring that a boolean column accepts nil, but we recommend using `allow_value` instead, like this:
it { should allow_value(nil).for(:imported) }
#### Qualifiers
##### with_message
Use `with_message` if you are using a custom validation message.
class Issue include ActiveModel::Model attr_accessor :severity validates_inclusion_of :severity, in: %w(low medium high), message: 'Severity must be low, medium, or high' end # RSpec describe Issue do it do should validate_inclusion_of(:severity). in_array(%w(low medium high)). with_message('Severity must be low, medium, or high') end end # Test::Unit class IssueTest < ActiveSupport::TestCase should validate_inclusion_of(:severity). in_array(%w(low medium high)). with_message('Severity must be low, medium, or high') end
##### with_low_message
Use `with_low_message` if you have a custom validation message for when a given value is too low.
class Person include ActiveModel::Model attr_accessor :age validate :age_must_be_valid private def age_must_be_valid if age < 65 self.errors.add :age, 'You do not receive any benefits' end end end # RSpec describe Person do it do should validate_inclusion_of(:age). in_range(0..65). with_low_message('You do not receive any benefits') end end # Test::Unit class PersonTest < ActiveSupport::TestCase should validate_inclusion_of(:age). in_range(0..65). with_low_message('You do not receive any benefits') end
##### with_high_message
Use `with_high_message` if you have a custom validation message for when a given value is too high.
class Person include ActiveModel::Model attr_accessor :age validate :age_must_be_valid private def age_must_be_valid if age > 21 self.errors.add :age, "You're too old for this stuff" end end end # RSpec describe Person do it do should validate_inclusion_of(:age). in_range(0..21). with_high_message("You're too old for this stuff") end end # Test::Unit class PersonTest < ActiveSupport::TestCase should validate_inclusion_of(:age). in_range(0..21). with_high_message("You're too old for this stuff") end
##### allow_nil
Use `allow_nil` to assert that the attribute allows nil.
class Issue include ActiveModel::Model attr_accessor :state validates_presence_of :state validates_inclusion_of :state, in: %w(open resolved unresolved), allow_nil: true end # RSpec describe Issue do it do should validate_inclusion_of(:state). in_array(%w(open resolved unresolved)). allow_nil end end # Test::Unit class IssueTest < ActiveSupport::TestCase should validate_inclusion_of(:state). in_array(%w(open resolved unresolved)). allow_nil end
##### allow_blank
Use `allow_blank` to assert that the attribute allows blank.
class Issue include ActiveModel::Model attr_accessor :state validates_presence_of :state validates_inclusion_of :state, in: %w(open resolved unresolved), allow_blank: true end # RSpec describe Issue do it do should validate_inclusion_of(:state). in_array(%w(open resolved unresolved)). allow_blank end end # Test::Unit class IssueTest < ActiveSupport::TestCase should validate_inclusion_of(:state). in_array(%w(open resolved unresolved)). allow_blank end
@return [ValidateInclusionOfMatcher]
# File lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb, line 233 def validate_inclusion_of(attr) ValidateInclusionOfMatcher.new(attr) end
The `validate_length_of` matcher tests usage of the `validates_length_of` matcher. Note that this matcher is intended to be used against string columns and not integer columns.
#### Qualifiers
##### is_at_least
Use `is_at_least` to test usage of the `:minimum` option. This asserts that the attribute can take a string which is equal to or longer than the given length and cannot take a string which is shorter.
class User include ActiveModel::Model attr_accessor :bio validates_length_of :bio, minimum: 15 end # RSpec describe User do it { should validate_length_of(:bio).is_at_least(15) } end # Test::Unit class UserTest < ActiveSupport::TestCase should validate_length_of(:bio).is_at_least(15) end
##### is_at_most
Use `is_at_most` to test usage of the `:maximum` option. This asserts that the attribute can take a string which is equal to or shorter than the given length and cannot take a string which is longer.
class User include ActiveModel::Model attr_accessor :status_update validates_length_of :status_update, maximum: 140 end # RSpec describe User do it { should validate_length_of(:status_update).is_at_most(140) } end # Test::Unit class UserTest < ActiveSupport::TestCase should validate_length_of(:status_update).is_at_most(140) end
##### is_equal_to
Use `is_equal_to` to test usage of the `:is` option. This asserts that the attribute can take a string which is exactly equal to the given length and cannot take a string which is shorter or longer.
class User include ActiveModel::Model attr_accessor :favorite_superhero validates_length_of :favorite_superhero, is: 6 end # RSpec describe User do it { should validate_length_of(:favorite_superhero).is_equal_to(6) } end # Test::Unit class UserTest < ActiveSupport::TestCase should validate_length_of(:favorite_superhero).is_equal_to(6) end
##### is_at_least + is_at_most
Use `is_at_least` and `is_at_most` together to test usage of the `:in` option.
class User include ActiveModel::Model attr_accessor :password validates_length_of :password, in: 5..30 end # RSpec describe User do it do should validate_length_of(:password). is_at_least(5).is_at_most(30) end end # Test::Unit class UserTest < ActiveSupport::TestCase should validate_length_of(:password). is_at_least(5).is_at_most(30) end
##### with_message
Use `with_message` if you are using a custom validation message.
class User include ActiveModel::Model attr_accessor :api_token validates_length_of :api_token, minimum: 10, message: "Password isn't long enough" end # RSpec describe User do it do should validate_length_of(:password). is_at_least(10). with_message("Password isn't long enough") end end # Test::Unit class UserTest < ActiveSupport::TestCase should validate_length_of(:password). is_at_least(10). with_message("Password isn't long enough") end
##### with_short_message
Use `with_short_message` if you are using a custom “too short” message.
class User include ActiveModel::Model attr_accessor :secret_key validates_length_of :secret_key, in: 15..100, too_short: 'Secret key must be more than 15 characters' end # RSpec describe User do it do should validate_length_of(:secret_key). is_at_least(15). with_short_message('Secret key must be more than 15 characters') end end # Test::Unit class UserTest < ActiveSupport::TestCase should validate_length_of(:secret_key). is_at_least(15). with_short_message('Secret key must be more than 15 characters') end
##### with_long_message
Use `with_long_message` if you are using a custom “too long” message.
class User include ActiveModel::Model attr_accessor :secret_key validates_length_of :secret_key, in: 15..100, too_long: 'Secret key must be less than 100 characters' end # RSpec describe User do it do should validate_length_of(:secret_key). is_at_most(100). with_long_message('Secret key must be less than 100 characters') end end # Test::Unit class UserTest < ActiveSupport::TestCase should validate_length_of(:secret_key). is_at_most(100). with_long_message('Secret key must be less than 100 characters') end
@return [ValidateLengthOfMatcher]
# File lib/shoulda/matchers/active_model/validate_length_of_matcher.rb, line 196 def validate_length_of(attr) ValidateLengthOfMatcher.new(attr) end
The `validate_numericality_of` matcher tests usage of the `validates_numericality_of` validation.
class Person include ActiveModel::Model attr_accessor :gpa validates_numericality_of :gpa end # RSpec describe Person do it { should validate_numericality_of(:gpa) } end # Test::Unit class PersonTest < ActiveSupport::TestCase should validate_numericality_of(:gpa) end
#### Qualifiers
##### only_integer
Use `only_integer` to test usage of the `:only_integer` option. This asserts that your attribute only allows integer numbers and disallows non-integer ones.
class Person include ActiveModel::Model attr_accessor :age validates_numericality_of :age, only_integer: true end # RSpec describe Person do it { should validate_numericality_of(:age).only_integer } end # Test::Unit class PersonTest < ActiveSupport::TestCase should validate_numericality_of(:age).only_integer end
##### is_less_than
Use `is_less_than` to test usage of the the `:less_than` option. This asserts that the attribute can take a number which is less than the given value and cannot take a number which is greater than or equal to it.
class Person include ActiveModel::Model attr_accessor :number_of_cars validates_numericality_of :number_of_cars, less_than: 2 end # RSpec describe Person do it do should validate_numericality_of(:number_of_cars). is_less_than(2) end end # Test::Unit class PersonTest < ActiveSupport::TestCase should validate_numericality_of(:number_of_cars). is_less_than(2) end
##### is_less_than_or_equal_to
Use `is_less_than_or_equal_to` to test usage of the `:less_than_or_equal_to` option. This asserts that the attribute can take a number which is less than or equal to the given value and cannot take a number which is greater than it.
class Person include ActiveModel::Model attr_accessor :birth_year validates_numericality_of :birth_year, less_than_or_equal_to: 1987 end # RSpec describe Person do it do should validate_numericality_of(:birth_year). is_less_than_or_equal_to(1987) end end # Test::Unit class PersonTest < ActiveSupport::TestCase should validate_numericality_of(:birth_year). is_less_than_or_equal_to(1987) end
##### is_equal_to
Use `is_equal_to` to test usage of the `:equal_to` option. This asserts that the attribute can take a number which is equal to the given value and cannot take a number which is not equal.
class Person include ActiveModel::Model attr_accessor :weight validates_numericality_of :weight, equal_to: 150 end # RSpec describe Person do it { should validate_numericality_of(:weight).is_equal_to(150) } end # Test::Unit class PersonTest < ActiveSupport::TestCase should validate_numericality_of(:weight).is_equal_to(150) end
##### is_greater_than_or_equal_to
Use `is_greater_than_or_equal_to` to test usage of the `:greater_than_or_equal_to` option. This asserts that the attribute can take a number which is greater than or equal to the given value and cannot take a number which is less than it.
class Person include ActiveModel::Model attr_accessor :height validates_numericality_of :height, greater_than_or_equal_to: 55 end # RSpec describe Person do it do should validate_numericality_of(:height). is_greater_than_or_equal_to(55) end end # Test::Unit class PersonTest < ActiveSupport::TestCase should validate_numericality_of(:height). is_greater_than_or_equal_to(55) end
##### is_greater_than
Use `is_greater_than` to test usage of tthe `:greater_than` option. This asserts that the attribute can take a number which is greater than the given value and cannot take a number less than or equal to it.
class Person include ActiveModel::Model attr_accessor :legal_age validates_numericality_of :legal_age, greater_than: 21 end # RSpec describe Person do it do should validate_numericality_of(:legal_age). is_greater_than(21) end end # Test::Unit class PersonTest < ActiveSupport::TestCase should validate_numericality_of(:legal_age). is_greater_than(21) end
##### even
Use `even` to test usage of the `:even` option. This asserts that the attribute can take odd numbers and cannot take even ones.
class Person include ActiveModel::Model attr_accessor :birth_month validates_numericality_of :birth_month, even: true end # RSpec describe Person do it { should validate_numericality_of(:birth_month).even } end # Test::Unit class PersonTest < ActiveSupport::TestCase should validate_numericality_of(:birth_month).even end
##### odd
Use `odd` to test usage of the `:odd` option. This asserts that the attribute can take a number which is odd and cannot take a number which is even.
class Person include ActiveModel::Model attr_accessor :birth_day validates_numericality_of :birth_day, odd: true end # RSpec describe Person do it { should validate_numericality_of(:birth_day).odd } end # Test::Unit class PersonTest < ActiveSupport::TestCase should validate_numericality_of(:birth_day).odd end
##### with_message
Use `with_message` if you are using a custom validation message.
class Person include ActiveModel::Model attr_accessor :number_of_dependents validates_numericality_of :number_of_dependents, message: 'Number of dependents must be a number' end # RSpec describe Person do it do should validate_numericality_of(:number_of_dependents). with_message('Number of dependents must be a number') end end # Test::Unit class PersonTest < ActiveSupport::TestCase should validate_numericality_of(:number_of_dependents). with_message('Number of dependents must be a number') end
##### allow_nil
Use `allow_nil` to assert that the attribute allows nil.
class Age include ActiveModel::Model attr_accessor :age validates_numericality_of :age, allow_nil: true end # RSpec describe Post do it { should validate_numericality_of(:age).allow_nil } end # Test::Unit class PostTest < ActiveSupport::TestCase should validate_numericality_of(:age).allow_nil end
@return [ValidateNumericalityOfMatcher]
# File lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb, line 277 def validate_numericality_of(attr) ValidateNumericalityOfMatcher.new(attr) end
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 describe Robot do it { should validate_presence_of(:arms) } end # Test::Unit 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 describe User 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
##### 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 describe Robot do it { should validate_presence_of(:arms).on(:create) } end # Test::Unit 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 describe Robot do it do should validate_presence_of(:legs). with_message('Robot has no legs') end end # Test::Unit class RobotTest < ActiveSupport::TestCase should validate_presence_of(:legs). with_message('Robot has no legs') end
@return [ValidatePresenceOfMatcher]
# File lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb, line 108 def validate_presence_of(attr) ValidatePresenceOfMatcher.new(attr) end