[rspec-devel] Stories vs. examples

Pat Maddox pergesu at gmail.com
Wed Nov 7 13:23:18 EST 2007

On Nov 7, 2007 6:15 AM, David Chelimsky <dchelimsky at gmail.com> wrote:
> On Nov 7, 2007 2:04 AM, Matthijs Langenberg <mlangenberg at gmail.com> wrote:
> > Would this also mean that the guy writing the story is defining the
> > functional part of the GUI?
> > Since it's the most outer layer of the system, would that be described in a
> > story first?
> > Like: "Given a user and a form with a button, when a user clicks the button,
> > then the world should come to an end."
> There should likely be both interaction stories like that AND business
> rule stories, like the one Dan uses in
> http://dannorth.net/2007/06/introducing-rbehave. If every story takes
> you through every step, they all become too big IMO.

I still haven't quite made up my mind about this.  At this point, I'm
expressing interactions in stories and business rules in specs.  I
don't really like Dan's account example - it's either too low-level
for my taste, or isn't quite low-level enough :)

Here's the account class as I would probably write it (completely
untested): http://pastie.caboo.se/115092

I could be picking nits here, and Dan and I just have a different
design style.  If I give an object a command, then I expect it to do
its work or fail hard.  So for the "savings account is overdrawn"
scenario, I'd need to work at a higher level or use the object in more
detail.  When doing Rails apps, I would just have a scenario where the
user submits a form, and the next page displays an error message and
the balances are unchanged.

I'm not certain of what to do if it's not a Rails app.  I might use a
higher abstraction such as a BankService which protects the user from
dirty exceptions.  So the transfer step might be

@transaction = bank_service.request_transfer @savings, @checking, 50
@transaction.should_not be_success
@transaction.error.should == "You do not have sufficient funds"

and then we'd still have the steps that verify the account balances
are unchanged.

Of course, now is the point where I admit that I think that's a
needless abstraction, and doesn't feel very OO to me.  But maybe you
reach a point where you do need to wrap it up like that.  I would much

@savings.transfer_to @checking, 50 rescue nil

again later verifying that the balances weren't touched.

So what am I getting at here?  Right now, I generally only use stories
at a very high level.  That means I perform an action from the user's
point of view, rather than telling an object to do something.  In this
case, I would have a spec that defines when #can_transfer? is true and
when it's false, and that #transfer_to blows up when the account
doesn't have sufficient funds.  It's really a design detail though,
and one that should be hidden from the user.

However I mentioned that I'm on the fence about all of that.  The key
question is why am I writing code that isn't driven by a story?
Specifically, if the only interaction point is a controller action,
why do I need code that raises an exception instead of just silently
failing?  The reason is that a controller action is never the only
interaction point.  In a Rails app I happily open up console and use
my business objects.  I need them to be more informative when
something fails.

But, that's a business process, and needs to be captured in a story.
So basically this all boils down to me wondering if I need to move
more stuff - particularly interactions with business objects - into


More information about the rspec-devel mailing list