opensoul.org

rspec: model.should be_valid

One of the things I always check when spec’ing is that the model that I just created is valid.

@mymodel.should be_valid

This uses RSpec’s predicate support (any call to be_something? calls something? on the target object), and returns a correct but very unhelpful error:

expected valid? to return true, got false

Here is a little rspec matcher that I threw together this morning to check if a model is valid and spit out the validation errors:

module Spec
  module Rails
    module Matchers
      class BeValid  #:nodoc:

        def matches?(model)
          @model = model
          @model.valid?
        end

        def failure_message
          "#{@model.class} expected to be valid but had errors:\n  #{@model.errors.full_messages.join("\n  ")}"
        end

        def negative_failure_message
          "#{@model.class} expected to have errors, but it did not"
        end

        def description
          "be valid"
        end

      end

      def be_valid
        BeValid.new
      end
    end
  end
end

Now, I get:

MyModel expected to be valid but had errors:
  Password confirmation can't be blank
  Email has already been taken

This is nothing fancy, but it’s the small stuff that make life meaningful, so I thought I would share it. Throw the matcher code above into your spec_helper and check if your models are valid.

update: added negative_failure_message so “model.should_not be_valid” will work

rspec, ruby, and testing April 18, 2007

11 Comments

  1. David Chelimsky David Chelimsky April 19, 2007

    Perfect use of custom matchers! Nice.

    Cheers,
    David

  2. Rabbit Rabbit August 1, 2007

    Ah… that’s how be_valid works. Newly generated model specs use the be_valid method, but I couldn’t find any documentation for it. Thanks for the heads up!

  3. Craig Buchek Craig Buchek August 5, 2007

    I threw this into spec/spec_helper.rb; is that the right place, or is there a better place to put this?

    Also, it wouldn’t work with should_not be_valid. I had to add this:


    def negative_failure_message
    “#{@model.class} expected to be invalid but was valid.\n”
    end

    Other than that, it’s been a great help in finding the source of problems when the results are not as I was expecting.

  4. Hans de Graaff Hans de Graaff November 6, 2007

    Would be nice to see this as part of the rspec rails plugin. Did you already submit a patch for it?

  5. Bryan Ray Bryan Ray December 8, 2007

    Thanks for the addition. Much appreciated.

  6. Gustav Paul Gustav Paul January 11, 2008

    nice one

  7. Edwin Moss Edwin Moss April 28, 2008

    thanks

  8. ttsuchi ttsuchi October 9, 2008

    thanks! this is great!

  9. Merci pour le post utile! Je n’aurais pas eu ce le contraire!

  10. David Zhang David Zhang July 26, 2011

    This is great, but how does it work now with what’s said here - https://github.com/dchelimsky/rspec/wiki/Custom-Matchers – ?

    I’m not sure where to put this code…

    (also, shouldn’t this be part of RSpec?)

  11. Zac Zheng Zac Zheng September 12, 2011

    Here’s an updated matcher for RSpec 2 I found on gist:
    https://gist.github.com/820666

My name is Brandon Keepers. I like to build things, usually in Ruby or JavaScript. I work at GitHub and live in Holland, MI.

Popular Posts