[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
prefer:
@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
stories.
Pat
More information about the rspec-devel
mailing list