[rspec-users] New article on "Listening to Your Specs" up on Ruby Advent 2008

Lenny Marks lenny at aps.org
Tue Dec 16 15:01:32 EST 2008


On Dec 9, 2008, at 10:40 PM, Avdi Grimm wrote:

> I contributed an article on BDD and RSpec to the Ruby Advent Calendar
> 2008, going over some of the rules I've collected for interpreting
> what your specs say about your design.  It can be found here:
> http://advent2008.hackruby.com/past/2008/12/10/ 
> listening_to_your_specs/
>
> -- 
> Avdi
>
>

I'm curious where others stand on the topic of object level specs  
with describe blocks named after methods.  I posted the comment below  
with my 2 cents.

-lenny

I agree with most of the points in this article, but not so much the  
part about:

<quote>
Contexts named after methods

A describe block should encapsulate a particular scenario: an object  
or set of objects in a specific configuration. If objects are nouns,  
and methods are verbs, then contexts should describe nouns, not verbs.
</quote>

I think this is more or less what Aslak was saying but I wanted to  
get more specific. IMO, using rspec to spec behavior at the object/ 
unit level, it often makes perfect sense to describe the behavior of  
the verbs(methods). I think the following contrived example would be  
fine. It clearly shows me the what this method does and what the  
scenarios it handles are.

describe Account, "#debit" #maybe 'debiting' is better, but #debit is  
actually more descriptive of the API which is the level I'm at here.
describe "with sufficient funds"
it "should reduce balance by debited amount"
it "should ..."
describe "with insufficient funds"
it "should raise an InsufficentFundsError"
it "should ...

Actually in the above example I probably would have started with the  
following and only grouped into nested contexts when I started  
repeating myself(e.g. repetition of 'when balance is sufficient')

describe Account, "#debit"
it "should reduce balance by debited amount when balance is sufficient"
it "should raise an InsufficentFundsError when insufficient"
..

<quote>
Examples named after methods

There is rarely a one-to-one relationship between desired behaviors  
and methods on an object. When you name an example after the method  
it tests, it’s a clue that you have started to think in  
“implementation brain” rather than “behavior brain”. You’re thinking  
“I know we are going to need a method “#foo” which does such-and-so,  
so I’ll just start spec-ing it now…”. Step back, and think about the  
behavior you are really interested in. You may find it changes how  
you write examples. Or, you may find that you didn’t need that method  
at all.
</quote>

I don't agree much with the above either. I think this the difference  
between speccing behavior at the application level vs. object level.  
I don't feel its a smell to get down to the object level when  
necessary. One of the benefits of BDD at the object/code level(as  
opposed to feature level) is helping to flesh out the API(what  
classes, what methods, what inputs/outputs) that implements a  
feature. New classes and methods spring into existence as I realize  
that there are details(a new responsibility) that I eventually want  
to drill into but would only be distracting or messy at the current  
level. Using object level examples to focus in on something in  
isolation is a valuable technique. Again, its all about focussing at  
the right level of granularity.

For ex. part of an 'update profile' feature might involve showing a  
user an error message if he/she submits invalid data. Now I wouldn't  
start off thinking, I'm going to need a User class with a validate  
method, but going from the outside in might eventually drive me to it  
so that I can drill into all the details of what constitutes valid  
data directly/in isolation, without being mixed in with a bunch of  
other stuff or extra setup. 


More information about the rspec-users mailing list