Dave, you make a good point. In our system, where we are converting a legacy database/application, we typically have no user stories and have the technical (or you could argue user) requirement that the database logic / constraints get converted. This is where we are typically just encoding all of the should_have_many, etcs. They at a first glance do seem like fragile and redundant tests but when you consider that the schema isn't in rails standard format, simple has_manys are not always going to work so we actually need to test our configuration of the associations.

-Mike

David Chelimsky wrote:
On Wed, Feb 18, 2009 at 11:31 PM, Stephen Eley <sfe...@gmail.com> wrote:
On Wed, Feb 18, 2009 at 10:42 PM, Mark Wilden <m...@mwilden.com> wrote:
On Wed, Feb 18, 2009 at 4:39 PM, Fernando Perez <li...@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.

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.

That's huge!

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 think this depends on whether or not error messages are part of the
conversation w/ the customer. If not, that seems fine.

I find that I'll spec validations directly, but not associations.
There's no need to say that a team has_many players when you have
examples like team.should have(9).players_on_the_field.

But my validation specs do tend to be closely tied to AR methods like
valid?(), which, as your example suggests, is impeding my ability to
choose a different ORM lib. Time for some re-thinking!

Cheers,
David

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

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

--
-Mike Gaffney (http://rdocul.us)

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

Reply via email to