[rspec-users] validate_presence_of

Zach Dennis zach.dennis at gmail.com
Thu Feb 19 10:05:42 EST 2009

On Thu, Feb 19, 2009 at 12:31 AM, Stephen Eley <sfeley at gmail.com> wrote:
> On Wed, Feb 18, 2009 at 10:42 PM, Mark Wilden <mark at mwilden.com> wrote:
>> On Wed, Feb 18, 2009 at 4:39 PM, Fernando Perez <lists at ruby-forum.com> wrote:
>>> What's the point in testing validates_presence_of for a model?
>> To make sure you wrote that line of code.
> And the circle spins round and round...
> Specs that mirror the code that closely are a bad idea, I think.  The
> problem with that example is that the syntax of the code is driving
> the syntax of the spec, even if the spec was written first.  You're no
> longer thinking about high-level behavior, you're thinking about the
> presence of a certain line in Rails.

A highly expressive declarative phrase has been pushed down to nothing
more than  "a certain line". :)

While I agree with you in general, I think the wrong approach is to
immediately disallow ourselves from using words or phrases that are
found in the implementation in the specs. Yes, validates_presence_of
can be used in the implementation, but it also serves as great,
readable, behaviour expressing documentation. I'm not going to fault
anyone or any spec where it is used, since the phrase itself is highly
communicative. I'd be more concerned with its implementation rather
than the fact that someone found it as a clear way to write attribute
requiring examples.

> I write those sorts of model specs a little differently.  I just poke
> at things and set expectations on whether they break.  I'd write this
> example like:
> describe User do
>  before(:each) do
>    @this = User.make_unsaved   # I use machinist for my factory methods
>  end
>  it "is valid" do
>    @this.should be_valid
>  end
>  it "can save" do
>    @this.save.should be_true
>  end
>  it "requires a login" do
>    @this.login = nil
>    @this.should_not be_valid
>  end
>  it "may have a password reminder" do
>    @this.password_reminder = nil
>    @this.should be_valid
>  end
>  it "does not allow duplicate logins" do
>    @that = User.make(:login => "EvilTwin")
>    @this.login = "EvilTwin"
>    @this.should_not be_valid
>  end
> end
> ...And so forth.  It's wordier, but very readable, and it doesn't rely
> on the validation being done with a specific Rails method.  In fact,
> when I shifted to using Merb and Datamapper, I didn't have to change
> these sorts of tests at all.
> Also, while I used to be very anal and write "should
> have(1).error_on(:login)" and such, I eventually realized that there's
> no point.  Checking on 'valid?' is entire and sufficient.  The first
> example proves that the default factory case is valid, so as long as
> we're only changing one thing at a time, we know that that's the thing
> that breaks validity.  (Or, in the case of "may have," *doesn't* break
> validity.)

I like the idea of having "may have" examples for optional attributes.

> --
> Have Fun,
>   Steve Eley (sfeley at gmail.com)
>   ESCAPE POD - The Science Fiction Podcast Magazine
>   http://www.escapepod.org
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users

Zach Dennis

More information about the rspec-users mailing list