rspec: model.should be_valid

rspec | ruby | testing April 18 2007

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

posted by brandon | updated September 25th 04:33 PM
comments feed

8 comments

  1. Perfect use of custom matchers! Nice.

    Cheers, David

    David Chelimsky David Chelimsky
    April 19, 2007 at 09:40 AM
  2. 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!

    Rabbit Rabbit
    August 01, 2007 at 06:50 PM
  3. 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.

    Craig Buchek Craig Buchek
    August 05, 2007 at 08:45 PM
  4. Would be nice to see this as part of the rspec rails plugin. Did you already submit a patch for it?

    Hans de Graaff Hans de Graaff
    November 06, 2007 at 03:23 PM
  5. Thanks for the addition. Much appreciated.

    Bryan Ray Bryan Ray
    December 08, 2007 at 12:42 PM
  6. nice one

    Gustav Paul Gustav Paul
    January 11, 2008 at 02:36 PM
  7. thanks

    Edwin Moss Edwin Moss
    April 28, 2008 at 05:08 PM
  8. thanks! this is great!

    ttsuchi ttsuchi
    October 09, 2008 at 10:35 PM

Speak your mind:

(Required)

(Required)


(You may use textile in your comments.)

About

I'm Brandon Keepers, a web application developer that likes beautiful code, valid markup and adherence to standards. As a part of Collective Idea in Holland, Michigan, I practice Agile software development primarily using Ruby on Rails.

-86.103171 42.785037

Contact:

more ยป

Syndicate