Show validation errors in RSpec be_valid output using a custom matcher

I’m getting into Rspec and loving it. So I was surprised when I get this pretty unhelpful message from a be_valid specification:

expected valid? to return true, got false

So I went looking for a way to see what errors there actually were in the validation. First I came upon rspec: model.should be_valid // opensoul.org. That looked good but it didn’t work for me on Rails 3 with Rspec 2. Then I found Creating a custom “be_valid” matcher for rspec_on_rails « nuby on rails, which has more details but still didn’t work. (Also the way I also found (My) RSpec best practices and tips | EggsOnBread, which is too good not to share.)

With some more searching I found a good walk-through on writing custom matchers RSpec 2 with an example of how to show errors on one specified field: solnic.eu / Custom RSpec-2 Matchers. I’m not sure how it’s different from the built-in errors_on. It also used the deprecated module Spec:

*****************************************************************
DEPRECATION WARNING: you are using a deprecated constant that will
be removed from a future version of RSpec.
<internal:lib/rubygems/custom_require>:29:in `require'
* Spec is deprecated.
* RSpec is the new top-level module in RSpec-2
***************************************************************

With the help of all the above, a version that works in Rails 3 and RSpec 2:

RSpec::Matchers.define :be_valid_verbose do
  match do |model|
    model.valid?
  end
  
  failure_message_for_should do |model|
    "#{model.class} expected to be valid but had errors:n #{model.errors.full_messages.join("n ")}"
  end

  failure_message_for_should_not do |model|
    "#{model.class} expected to have errors, but it did not"
  end

  description do
    "be valid"
  end
end

Change the name to “be_valid” if you want. That works but I don’t like replacing standard stuff. Guess I’m not a Rubyist yet.

Is there a way to get this functionality without writing a custom matcher? Is there a safer way to override the be_valid?

This entry was posted in Coding and tagged , . Bookmark the permalink. Both comments and trackbacks are currently closed.
  • Subscribe

    Subscribe to all posts by feed.
  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 3 other subscribers