# Lazy evaluation and scoping

**URL:** <https://www.ruby-forum.com/t/lazy-evaluation-and-scoping/156768>\
**Category:** Rails\
**Created:** [January 2, 2009, 6:12pm UTC](https://www.ruby-forum.com/t/lazy-evaluation-and-scoping/156768 "2009-01-02T18:12:48Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![davidtl](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/35a633/32.png) [@davidtl](https://www.ruby-forum.com/u/davidtl)\
**Post date:** [January 2, 2009, 6:12pm UTC](https://www.ruby-forum.com/t/lazy-evaluation-and-scoping/156768/1 "2009-01-02T18:12:48Z")

</div>

Take a look at the #should\_require\_login\_for inside this pastie (it’s a  
Shoulda macro): [http://pastie.org/350658](http://pastie.org/350658)

#should\_require\_login\_for takes an action name and a Proc. The method is  
meant to be used like this in my functional tests:

should\_require\_login\_for  
:new =\> Proc.new { get :new },  
:create =\> Proc.new { post :create },  
…

What this is basically supposed to do is:

1. Loop through each action.
2. Create a Shoulda #context
3. #setup a test by calling the Proc containing “get :new” or something.
4. Assert a redirection to the login page inside the #should block.

So this should test if an action requires login or not. But my problem  
is, that I’m getting this error:

NoMethodError: undefined method `get’ for PagesControllerTest:Class  
./test/functional/pages\_controller\_test.rb:7

Notice that the error is appearing in the PagesControllerTest and NOT  
inside the Shoulda macro. Using a lambda instead of a Proc simply  
“postpones” the error message to the Shoulda macro, but it’s still the  
same message.

My question is: How do I get access to the #get, #post, #put, and  
#delete methods in my Proc or lambda? Any help appreciated. 🙂

---

<div class="post-metadata">

**Author:** ![davidtl](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/35a633/32.png) [@davidtl](https://www.ruby-forum.com/u/davidtl)\
**Post date:** [January 3, 2009, 12:08pm UTC](https://www.ruby-forum.com/t/lazy-evaluation-and-scoping/156768/2 "2009-01-03T12:08:03Z")

</div>

David T. wrote:

> My question is: How do I get access to the #get, #post, #put, and  
> #delete methods in my Proc or lambda? Any help appreciated. 🙂

If you need further details, please go ahead and ask. 🙂

–  
David T…  
[http://twitter.com/datra](http://twitter.com/datra)

---

<div class="post-metadata">

**Author:** ![davidtl](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/35a633/32.png) [@davidtl](https://www.ruby-forum.com/u/davidtl)\
**Post date:** [January 3, 2009, 12:15pm UTC](https://www.ruby-forum.com/t/lazy-evaluation-and-scoping/156768/3 "2009-01-03T12:15:39Z")

</div>

On 2 Jan 2009, at 17:12, David T. wrote:

> :new =\> Proc.new { get :new },
> 
> My question is: How do I get access to the #get, #post, #put, and  
> #delete methods in my Proc or lambda? Any help appreciated. 🙂

First off I know absolutely nothing about shoulda. That said blocks  
are closures, so in particular they remember the value of self when  
they were defined so if your test looks like

class SomeTestCase \< Test::Unit::TestCase  
some\_macro :new =\> Proc.new {…}  
end

then for that block, self is and always will be SomeTestCase. The  
easiest thing to do would be to have your setup method pass self to  
the proc and have the proc call get/post/etc… on that.

Fred

---

<div class="post-metadata">

**Author:** ![davidtl](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/35a633/32.png) [@davidtl](https://www.ruby-forum.com/u/davidtl)\
**Post date:** [January 3, 2009, 12:43pm UTC](https://www.ruby-forum.com/t/lazy-evaluation-and-scoping/156768/4 "2009-01-03T12:43:29Z")

</div>

Frederick C. wrote:

> > :new =\> Proc.new { get :new },
> > 
> > My question is: How do I get access to the #get, #post, #put, and  
> > #delete methods in my Proc or lambda? Any help appreciated. 🙂
> 
> First off I know absolutely nothing about shoulda.

Shoulda is actually just a collection of test helpers: the #setup method  
that runs before each test, the #should that defines a test, and the  
#context that encapsulates a context, e.g.:

context “GET new” do  
context “when logged in” do  
setup do  
log\_in  
get :new  
end

```
should_respond_with :success

should "do something" do
  assert something
end

```

end  
end

> That said blocks  
> are closures, so in particular they remember the value of self when  
> they were defined so if your test looks like
> 
> class SomeTestCase \< Test::Unit::TestCase  
> some\_macro :new =\> Proc.new {…}  
> end
> 
> then for that block, self is and always will be SomeTestCase. The  
> easiest thing to do would be to have your setup method pass self to  
> the proc and have the proc call get/post/etc… on that.

That might work. I tried a different approach, it’s not quite as elegant  
but I use it this way:

should\_require\_login :post, :create  
should\_require\_login :get, :edit, :id =\> Page.first.id

Take a look at the method definition here: [http://pastie.org/351489](http://pastie.org/351489) The  
first argument is the HTTP method you want to use. Second argument is  
what action to test. And the third is additional parameters you want to  
pass to the action.

It works fine, but thanks anyway, Frederick. If anyone else could find  
the #should\_require\_login method helpful, you are free to use it. 🙂
