Olly Legg home

Custom rspec Matcher for Strict Validations

2nd Feb 2013

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.