On 10/16/07, David Chelimsky <[EMAIL PROTECTED]> wrote:
> On 10/16/07, Pat Maddox <[EMAIL PROTECTED]> wrote:
> > Personally, if I wanted to extract this pattern, I would use a custom
> > expectation matcher.
>
> ... which would probably be implemented like this under the hood:
>
> def matches?(target)
>   target.should_receive(:validates_presence_of).with(@expected)
>   load "#{RAILS_ROOT}/app/models/#{target.humanize}.rb"
> end
>
> No?

No.  I actually showed it in my post, though I suppose I did it in a
slightly confusing format.  I would implement it like so:

def matches?(target)
  instance = Target.new
  instance.should_not be_valid
  instance.error_messages.on(@expected).should == "can't be blank"
end

A couple key points:
1. AR defines validates_presence_of, but your subclass is responsible
for doing the actual validation
2. This particular code is lightweight enough that it's okay to use
the real implementation.  You don't get a big performance hit like you
do when you're creating/updating objects in the db and their
associations
3. When you call MyModel.new when spec'ing business logic, it hits the
db to get the column info.  You already have a coupling to the DB
simply by using AR, so I don't think that's a good reason to prefer
expecting the validates_* method call.  If perf does become an issue,
you can stub out the columns and remove the db dependency all
together.  Jay Fields mentions that in a blog, and I think he's insane
(at least the way he showed), but it should be easy enough to preload
all the column info from schema.rb.  In fact I think I heard of that
technique from someone on this list.

Pat
_______________________________________________
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users

Reply via email to