It works with Rails >=4.0. (For Rails >=3.0 use version 1.x) Helps me test my validations on Models with less code. Assuming that Rails validations are already tested, by Rails, then when I have a validation on an attribute of a Model, I just want to test whether the validation is there. Nothing more.
Assuming that you have a Model like the following:
class MyAwesomeModel < ActiveRecord::Base validates :last_name, :presence => true end
In your test:
it "last name has to be present" do expect(ActiveModel::Validations::PresenceValidator.is_attached?(MyAwesomeModel, :last_name)).to be true end
will test that your last_name attribute on the model MyAwesomeModel has a :presence validation attached. Note that ActiveModel::Validations::PresenceValidator is the class that comes with Rails ActiveModel.
Note: “attached?” is an alias for “is_attached?” and you can use whatever you feel like better.
Optionally, you can also check whether the correct options are attached too. So, if you have a Model like:
class MyAwesomeModel < ActiveRecord::Base validates :last_name, :length => { :minimum => 3, :maximum => 60 } end
In your test:
it "last name should not be of correct length" do
# you do not have to check for all options
it { expect(ActiveModel::Validations::LengthValidator.is_attached?(MyAwesomeModel, :last_name, { :minimum => 3 })).to be true }
it { expect(ActiveModel::Validations::LengthValidator.is_attached?(MyAwesomeModel, :last_name, { :maximum => 60 })).to be true }
# or you can check for all
it { expect(ActiveModel::Validations::LengthValidator.is_attached?(MyAwesomeModel, :last_name, { :minimum => 3, :maximum => 60 })).to be true }
# or you can ask for those and only those, i.e. exact content match
it { expect(!ActiveModel::Validations::LengthValidator.is_attached?(MyAwesomeModel, :last_name, { :maximum => 60 }, true)).to be true }
it { expect(ActiveModel::Validations::LengthValidator.is_attached?(MyAwesomeModel, :last_name, { :minimum > 60, :maximum => 60 }, true)).to be true }
end
Another example with with_options:
class User < ActiveRecord::Base with_options :if => :is_admin? do |admin| admin.validates :password, :length => { :minimum => 10 } admin.validates :username, :presence => true end end
You can test this as follows:
test "user admin validators" do it { expect(ActiveModel::Validations::LengthValidator.is_attached?(User, :password, { :minimum => 10, :if => :is_admin? })).to be true } it { exepct(ActiveModel::Validations::PresenceValidator.is_attached?(User, :username, { :if => :is_admin? })).to be true } end
In the file validator_attachment_test.rb you will see a lot of tests that I run to test the gem and you can get ideas on you should use your assertions. You will see there an example with a custom validator too.
It is easy to derive the class of the validator. The rule of thumb is that all Validators are ActiveModel validators with one exception that of :uniqueness, which is an ActiveRecord Validator. However, here is a list that can help you:
- :acceptance
-
ActiveModel::Validations::AcceptanceValidator
- :confirmation
-
ActiveModel::Validations::ConfirmationValidator
- :exclusion
-
ActiveModel::Validations::ExclusionValidator
- :format
-
ActiveModel::Validations::FormatValidator
- :inclusion
-
ActiveModel::Validations::InclusionValidator
- :length
-
ActiveModel::Validations::LengthValidator
- :numericality
-
ActiveModel::Validations::NumericalityValidator
- :uniqueness
-
ActiveRecord::Validations::UniquenessValidator
- :presence
-
ActiveModel::Validations::PresenceValidator
If you find a problem with validator_attachment, please open an issue on issue on GitHub
See the CHANGELOG for release notes and versions of this gem. Please, note that gem follows Semantic Versioning but patch version number will be increased if either bug fixes are introduced (as Semantic Versioning defines) or if tests or documents are added.