[rspec-users] Stopping Example Execution?

Zach Dennis zach.dennis at gmail.com
Thu Jul 3 00:03:14 EDT 2008


One good way (IMO) to approach before filters is to always stub them when it
comes time to testing a controller action. And to test the filter separately
in isolation. For example if you need to define an application level before
filter in ApplicationController, then test the filter in isolation using an
application_controller_spec.

If you'd like to know that your controllers which subclass
ApplicationController use them, you can easily add a declarative style "it"
helper which verifies that the filter is being used, but doesn't test the
filter (since you already did that in your application_controller_spec.

I know this doesn't help you now, but it is a useful technique which you can
use in the future to limit the maintenance nightmare that can come along
with things like before filters,

Zach

On Wed, Jul 2, 2008 at 10:58 PM, Britt Mileshosky <mileshosky at hotmail.com>
wrote:

>
>
> ----------------------------------------
> > From: mileshosky at hotmail.com
> > To: rspec-users at rubyforge.org
> > Date: Wed, 2 Jul 2008 10:13:59 -0700
> > Subject: Re: [rspec-users] Stopping Example Execution?
> >
> >
> >
> > ----------------------------------------
> >> Date: Wed, 2 Jul 2008 06:15:10 -0500
> >> From: dchelimsky at gmail.com
> >> To: rspec-users at rubyforge.org
> >> Subject: Re: [rspec-users] Stopping Example Execution?
> >>
> >> On Mon, Jun 30, 2008 at 5:11 PM, Britt Mileshosky
> >>  wrote:
> >>>
> >>> n Sun, Jun 29, 2008 at 12:20 PM, David Chelimsky wrote:
> >>> On Jun 29, 2008, at 11:18 AM, Britt Mileshosky 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 ...
> >>>
> >>> My instinct about this is that it would encourage long methods because
> it would make it less painful to test them, so I would be adverse to
> anything that let's you short circuit the method.
> >>>
> >>> Anybody else have opinions on that?
> >>>
> >>>
> >>>
> >>> I'm just catching up on email now after being sick for the past six
> days, but health aside my opinion is that I agree with David's opinion.
> Rather than focusing on how-to write easier tests that complain less, start
> focusing on how-to write the right tests that complain when necessary.
> >>>
> >>> One of the benefits associated with feeling the pain of a test is that
> it may be a sign to re-assess and refactor your code. This usually happens
> early enough that it only takes a few minutes. Short circuiting essentially
> gives you the ability to not feel the pain. Its like CIPA [0], but for code.
> I would fear that the code would get so bad that by the time the test cried
> with pain your code was already beyond easy repair and instead required
> invasive surgery.
> >>>
> >>> Tests are part of the nervous system of your application. When they
> hurt, they're telling you something isn't right and that it should be
> addressed,
> >>>
> >>>
> >>>
> >>> I wouldn't really say that anything I have been presenting has been a
> result of 'pains',
> >>> more so an observation on how an example group with other example
> groups can be much more readable
> >>> for myself and for other developers when they need to read the specs.
> Stubbing everything at the top doesn't
> >>> make complete sense. Why not stub inside the example group that has a
> NICE describe statement telling you
> >>> what this stubbing is related to. We can't do this because the first
> examples will blow up due to having to execute
> >>> all the code.
> >>>
> >>> Take the 2 examples:
> >>>
> >>>
> ------------------------------------------------------------------------------------------------------------------------
> >>> PeopleController
> >>> # stub everything way up here at the top where these
> >>> # definitions are out of context (by means of position) with following
> examples
> >>> #
> >>> # stub controller requirments
> >>> # stub logged in requirement
> >>> # stub account requirement
> >>> # stub no account requirement
> >>> # stub account owns person
> >>> # stub account doesn't own person
> >>>
> >>>
> >>> PeopleController with before filters
> >>> - should require user
> >>>
> >>> 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 ...
> >>>
> >>>
> ------------------------------------------------------------------------------------------------------------------------
> >>> PeopleController
> >>> # stub the minimum needed to get to the first example group up and
> running
> >>>
> >>> PeopleController with before filters
> >>> - should require user
> >>>
> >>> PeopleController with a logged in user
> >>> # stub logged in requirement
> >>> - should find user
> >>>
> >>> PeopleController with a logged in user who has an account
> >>> # stub account requirement
> >>> - should find account
> >>>
> >>> PeopleController with a logged in user who doesnt have an account
> >>> # stub no account requirement
> >>> - shouldn't find account
> >>> - should redirect ...
> >>>
> >>> PeopleController with a logged in user who has an account the person
> belongs to
> >>> # stub account owns person
> >>> - 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
> >>> # stub account doesn't own person
> >>> - should not find person
> >>> - should ...
> >>>
> >>>
> ------------------------------------------------------------------------------------------------------------------------
> >>>
> >>> I prefer the second group, but unfortunately I am not able to write my
> specs in this organized fashion.
> >>> Just sayin.
> >>
> >> I appreciate the communication value you're looking for, and you can
> >> get it by stubbing everything you need to keep execution going
> >> before(:each) example and then set message expectations
> >> (should_receive) inside each example that help tell the story of that
> >> example.
> >>
> >> PeopleController
> >> # stub everything way up here at the top where these
> >> # definitions are out of context (by means of position) with following
> examples
> >> #
> >> # stub controller requirments
> >> # stub logged in requirement
> >> # stub account requirement
> >> # stub no account requirement
> >> # stub account owns person
> >> # stub account doesn't own person
> >>
> >> PeopleController with before filters
> >> - should require user
> >>
> >> PeopleController with a logged in user
> >> # expect logged in query
> >> - should find user
> >>
> >> PeopleController with a logged in user who has an account
> >> # expect logged in query
> >> # expect account query
> >> - should find account
> >>
> >> etc
> >>
> >> HTH,
> >> David
> >
> > Yep, thats exactly what I've been practicing, and while its not exactly
> what I want, it does work nicely.
> > Thank you David
>
>
> I'm gonna make another REALLY strong case for allowing the ability to stop
> example execution and test code incrementally. I currently have over  1700
> examples for the current application I'm working on, and one little line of
> code that I added in my App controller ( before_filter :set_location )
> brought on almost 1100 errors across my tests.  Now I know people will say
> that the requirements weren't understood at the beginning of the application
> and that it could have been avoided with better planning... but this isn't
> the case.
>
> I now have to go into each of my controller tests and add the stub into
> every before declaration to clear up my errors.  Not fun, and could've been
> avoided completely.
>
> Britt
>
> _________________________________________________________________
> Enter the Zune-A-Day Giveaway for your chance to win — day after day after
> day
>
> http://www.windowslive-hotmail.com/ZuneADay/?locale=en-US&ocid=TXT_TAGLM_Mobile_Zune_V1
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users
>



-- 
Zach Dennis
http://www.continuousthinking.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20080703/35195ea2/attachment.html>


More information about the rspec-users mailing list