On Sun, Jun 29, 2008 at 9:18 AM, Britt Mileshosky
<mileshosky at hotmail.com> wrote:
>> However, do you see where something like a return statement or end example statement could be beneficial?
> If you are working from the top down with your controller action execution, then you only need to test your expectation
> and then bail out of your action. No need to further test or meet requirements on anything else in that action because your
> single test has been met.
>> - in my example for making sure I find a user, I'd like to end execution once I DID find the user, i shouldn't have to satisfy
> requirements about finding an account and a person... I'll write those expectations later in another nested describe group, as you
> can see here, in a top down process
>> PeopleController with a logged in user
> - should find user
>> PeopleController with a logged in user who has an account
> - should find account
>> PeopleController with a logged in user who doesnt have an account
> - shouldn't find account
> - should redirect ...
>> PeopleController with a logged in user who has an account the person belongs to
> - should find person
> - should assign person for the view
>> PeopleController with a logged in user who has an account the requested person does not belong to
> - should not find person
> - should ...
Hi Britt,
Quick little thought experiment for you:
Imagine you write the examples as you have described, stubbing only
the minimum amount of things necessary and then ending the example
once you've reached a certain point. So for the action
def some_action
@user = self.current_user
@account = self.current_account if self.has_account?
@person = @account.people.find(params[:person])
end
your first example only runs until current_user, your second example
runs only until has_account, and your third one runs only until
account.people.find. So far so good.
What happens when you change the implementation to:
def some_action
@user = self.current_user
if self.has_account?
@account = self.current_account
@person = @account.people.find(params[:person])
end
end
which I could totally see doing, given that the original
implementation will raise an error on the @account.people call on
those occasions where has_account? returns false, making @account nil.
Can you spot the problem? Your specs will now fail because you had
only stubbed enough to get to a particular line. The specs are very
tightly coupled to the implementation, which sucks.
Also, if you were to do this incremental stubbing, you would have a
hard time moving examples around, because the nested examples would
rely on context set up by the parents.
This technique, after looking a bit more deeply at it, would lead to
specs that are tightly coupled to the implementation and to each
other. Tight coupling is usually bad, and tight coupling from both
angles is a recipe for total frustration.
I hope that is helpful.
Pat