I've been using ActiveModel's strict validations quite a lot in Rails v3.2 applications I've been working on. I've been testing them using rspec's raise_error
matcher. However there's quite a lot of boilerplate code for each assertion.
it "requires a name" do
expect {
subject.name = ''
subject.valid?
}.to raise_error(ActiveModel::StrictValidationFailed)
end
Today I got a chance to work on some custom matchers for asserting strict validation passes or failures. These matchers provide a much terser API for verifying strict validations.
it "requires a name" do
subject.name = ''
expect(subject).to fail_strict_validations
subject.name = 'Joe Bloggs'
expect(subject).to pass_strict_validations
end
I defined the following matchers in spec/support/matchers/strict_validation_matcher.rb
, which gets automatically loaded by the default 'spec_helper.rb'.
matcher = ->(model) do
begin
model.valid?
true
rescue ActiveModel::StrictValidationFailed
false
end
end
RSpec::Matchers.define :pass_strict_validations do
match(&matcher)
end
RSpec::Matchers.define :fail_strict_validations do
match do |model|
!matcher.call(model)
end
end
I've added the code to a Gist. Use it, fork it, modify it.