[rspec-users] before(:each) <- need some clarification

Matt Wynne
2011-04-27T21:15:15Z

Hi,

On 27 Apr 2011, at 20:55, Sergio Ruiz wrote:

> i am setting up a few objects that are interrelated for use in an rspec
> test..
>
> something like:
>
> describe Dimension do
>
> before(:each) do
> text = "string here"

This defines a local variable ''text'' which lives for the
duration of the before block. It can''t be seen by the #it block
(example) below, because it''s gone out of scope.

> end
>
> it "should puts string" do
> puts text
> end
>
> end
>
> when i run this, i get an error: undefined local variable or method
> `text''
>
> am doing something wrong?
>
> thanks!

What people don''t realise is that #describe just creates an instance of
a class, called ExampleGroup. Think of the ''before'' block and
the ''it'' blocks as methods on that class. If you defined a
private variable in one method on a class, you wouldn''t expect to be
able to see it from another one, would you?

Here''s what we used to do in this kind of situation:

    describe Dimension do
      before(:each) do
        @text = "string here"
      end

      it "should puts string" do
        puts @text
      end
    end

Because, as I expect you know, instance variables *can* be seen between methods
on a class. However, some people found the instance variables noisy, or wanted
to lazy initialise them, so started doing this:

    describe Dimension do
      def text
        @text ||= "string here"
      end

      it "should puts string" do
        puts text
      end
    end

As I said, #describe just creates a class, so you can define methods on that
class if you like. Now our puts statement is calling the #text method that
we''ve defined.

This is such a common pattern, that in RSpec 2, David introduced #let blocks,
which let you refactor the above code to look like this:

    describe Dimension do
      let(:text) { "string here" }

      it "should puts string" do
        puts text
      end
    end

Make sense?

cheers,
Matt

--
Freelance programmer & coach
Founder, http://relishapp.com
+44(0)7974430184 | http://twitter.com/mattwynne