On May 26, 2010, at 9:37 PM, Nadal wrote:

> Here is my spec.
> 
> describe Exception2db do
>  context "attributes" do
>    subject { Exception2db.create(:exception => $exception_data_xml) }
> 
>    specify { subject.controller.should == 'exception2db/main' }
>    specify { subject.error_message.should == 'RuntimeError: 46' }
>    specify { subject.user_agent.should == "Mozilla/5.0 (Macintosh; U;
> Intel Mac OS X 10_6_3; en-US) AppleWebKit/533.4 (KHTML, like Gecko)
> Chrome/5.0.375.38 Safari/533.4" }
>  end
> end
> 
> Here is specdoc.
> 
> Exception2db attributes
> - should == "exception2db/main"
> - should == "RuntimeError: 46"
> - should == "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; en-US)
> AppleWebKit/533.4 (KHTML, like Gecko) Chrome/5.0.375.38 Safari/533.4"
> 
> All the tests are passing. However the specdoc message is not very
> clean.
> 
> How can I improve the message? What am I missing? The idea of wrapping
> each of my specify inside "it" to just to have better message is not
> very DRY.

I look at it the other way: accepting unclear messages just to keep things DRY 
is missing the point.

DRY is about reducing duplication of concepts, not letters. At its heart, DRY 
is about maintenance. Duplication can come in very sinister forms, like two 
methods with different names on two different objects that accomplish the same 
task. That's the sort of duplication that kills maintenance because a new 
requirement comes in and you don't even realize you have two places to change 
in the code base.

Consider the following two examples:

it "concats the first and last name" do
  first_name = "David"
  last_name = "Chelimsky"
  person = Person.new(
    :first_name => first_name,
    :last_name => last_name
  )
  person.full_name.should == "#{first_name} #{last_name}"
end

it "concats the first and last name" do
  person = Person.new(
    :first_name => "David",
    :last_name => "Chelimsky"
  )
  person.full_name.should == "David Chelimsky"
end

Which one is DRYer? You could argue the first one is, because the string 
literals are not repeated. You could argue that the second one is, because the 
variable names are not repeated. You might argue the first one is because, even 
though the variable names are repeated, the failure message you get if you type 
"frist_name" will be very informative. You might argue that typing "Chelmisky" 
in the second one would also give you an informative message. Also, the first 
one very likely duplicates the actual implementation of the full_name method. 
And on, and on, and on, and on.

Here's what I don't really think you can argue against: the second one is 
easier to read and understand.

In the example you gave, I have absolutely no idea what those specs are telling 
me about the Exception2db object. After some study, I _think_ I understand, but 
it took a minute. What I'd like to see in the specdoc output is something like:

Exception2db
  stores the controller
  stores the runtime error
  stores the user agent

Now I know what this thing DOES. Sure, the spec is going to have more lines in 
it, but the concepts expressed in the specdoc are _different_ from the concepts 
in the expectations. In my book, that's not a DRY violation at all.

HTH,
David

ps - there is some irony in the fact that I keep repeating myself on this exact 
topic on this list. I think I need to write this up in a blog post and point 
people to that in the future. Now THAT would be DRY.
  
_______________________________________________
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users

Reply via email to