[rspec-users] How can I use nested "before" functions?

David Chelimsky
Sat, 04 Dec 2010 02:54:51 -0000

On Dec 3, 2010, at 8:11 PM, Erik Helin wrote:

>
>
> On Fri, Dec 3, 2010 at 16:43, Matt Wynne <matt at mattwynne.net>
wrote:
>
> On 1 Dec 2010, at 05:47, helino wrote:
>
> > Hi everyone,
> >
> > I''ve started learning Ruby and RSpec, and I''ve ran
into a small
> > problem. I have one "before" functions which run before all
my
> > descriptions and the context in the spec, and then I have another
> > "before" function inside a context, which is set to run once
before
> > all the "it" inside that context.
> >
> > My problems is that the outer "before" does not run prior to
the
> > "before" inside my context. This creates an error, since the
"before"
> > inside the context relies on a variable being created in the outmost
> > "before".
> >
> > Is this how it is supposed to be, or am I doing something wrong?
> >
> > Gists:
> > * "rspec spec --backtrace" output:
https://gist.github.com/723021
> > * router.rb: https://gist.github.com/723020
> > * router_spec.rb: https://gist.github.com/723015
>
> You''re getting before(:each) and before(:all) mixed up.
>
> before(:each) is the default. You really don''t want to use
before(:all) in anything but exceptional circumstances. Right now you have a mix
of the two, which I think it why you''re getting the suprising
behaviour.
>
> I know that I''m mixing before(:each) and before(:all). What
I''m wondering is the rules for how they interact? Are then any
"scoping" rules in RSpec?

Yep:
http://relishapp.com/rspec/rspec-core/v/2-2/dir/hooks/before-and-after-hooks

> I think that it makes sense that a before(:all) defined in a context on
which a before(:each) is already applied gets run after the before(:each) has
run, but that''s just my opinion.

It''s a combination of scoping and ordering, but what you ask runs
counter to the rules we have in place.

As Matt pointed out, before(:all) is really intended for exceptional
circumstances. Also, before(:each)''s are inherited, while
before(:all)''s are not (they are only run once). Consider:

describe "outer" do
  before(:all) { puts "outer before all" }
  before(:each) { puts "outer before each" }
  example { puts "outer example 1" }
  example { puts "outer example 2" }
  after(:each) { puts "outer after each" }
  after(:all) { puts "outer after all" }

  context "inner" do
    before(:all) { puts "inner before all" }
    before(:each) { puts "inner before each" }
    example { puts "inner example 1" }
    example { puts "inner example 2" }
    after(:each) { puts "inner after each" }
    after(:all) { puts "inner after all" }
  end
end

Here''s the output reflecting the order (w/ spacing to provide some
context):

outer before all

outer before each
outer example 1
outer after each

outer before each
outer example 2
outer after each

inner before all

outer before each
inner before each
inner example 1
inner after each
outer after each

outer before each
inner before each
inner example 2
inner after each
outer after each

inner after all

outer after all

That all make sense?

Cheers,
David


> >
> > I''m using Ruby version 1.9.2p0 with rvm on Mac OS X 10.6.5
and RSpec
> > 2.1.0.
> >
> > Thanks for a wonderful framework!
> >
> > Best regards,
> > Erik
> > _______________________________________________
> > rspec-users mailing list
> > rspec-users at rubyforge.org
> > http://rubyforge.org/mailman/listinfo/rspec-users
>
> cheers,
> Matt
>
> matt at mattwynne.net
> 07974 430184
>
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users
>
> Thanks for your answer!
> Erik
>
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users

-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://rubyforge.org/pipermail/rspec-users/attachments/20101203/7bba61e1/attachment-0001.html>