Forum: Ruby on Rails Functional tests and protected actions

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
9618e8fca8d72bf01814276c53c2568c?d=identicon&s=25 Robert MannI (Guest)
on 2006-06-06 08:29
(Received via mailing list)
Hello!

I have certain methods in my Application Controller, that I need to
access.
Namely ApplicationController#logged_in_user

The problem is, that when I try to access it, I get:

NoMethodError: protected method `logged_in_user' called for
#<AdminController>


Any ideas how I can circumvent that?

Or are functional tests really not suited for any kind of logins and
session
work? I don't see why I should move everything to a Integration Test
just
because I added user logins.

Any ideas?

Thanks,
Rob
7c4087d053eb02d099a17d91ba5e33b5?d=identicon&s=25 Brian Hughes (Guest)
on 2006-06-06 16:38
(Received via mailing list)
On Jun 6, 2006, at 02:28 AM, Robert MannI wrote:
> I have certain methods in my Application Controller, that I need to
> access. Namely ApplicationController#logged_in_user
>
> The problem is, that when I try to access it, I get:
>
> NoMethodError: protected method `logged_in_user' called for
> #<AdminController>
>
> Any ideas how I can circumvent that?

The simplest way of dealing with this is to have your private/
protected controller methods only set instance variable values. That
way, you can run an assert on the value from within the context of
calling testing a public controller action/method.

However, given that what you are looking to test is a method of your
Application Controller, my guess is that you are calling it via a
before_filter. If that's the case, then what you are probably going
to need to do is rely on the session object. If you look at my other
post on functional tests you'll see how you can set session values
when you call into your controller actions.

> Or are functional tests really not suited for any kind of logins
> and session work? I don't see why I should move everything to a
> Integration Test just because I added user logins.

Integration tests are for testing the browser process across multiple
actions and controllers. Basically, you can use Integration tests to
completely verify your user stories, front to back. However, if you
haven't already verified your business logic (ie. Models) with Unit
tests and your individual controller actions with Functional tests,
moving up to Integration tests would be a mistake...

-Brian
58479f76374a3ba3c69b9804163f39f4?d=identicon&s=25 Eric Hodel (Guest)
on 2006-06-07 12:07
(Received via mailing list)
On Jun 5, 2006, at 11:28 PM, Robert MannI wrote:

>
> Any ideas how I can circumvent that?

protected unless $TESTING

set $TESTING to true in your test case.

--
Eric Hodel - drbrain@segment7.net - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com
9618e8fca8d72bf01814276c53c2568c?d=identicon&s=25 Robert MannI (Guest)
on 2006-06-08 22:19
(Received via mailing list)
Brian Hughes: I like to rely on my getters and setters. I don't want to
know
how my class behaves, I just want to use it

Eric Hodel: I don't like the idea of changing my code for the tests


I'll might just change the protected property dynamically, just for the
duration of the tests.
7c4087d053eb02d099a17d91ba5e33b5?d=identicon&s=25 Brian Hughes (Guest)
on 2006-06-09 16:47
(Received via mailing list)
On Jun 8, 2006, at 04:19 PM, Robert MannI wrote:
> Brian Hughes: I like to rely on my getters and setters. I don't
> want to know how my class behaves, I just want to use it

I'm not sure how to respond to this... at what point did I tell you
to not rely on your "getters and setters"?

As for how your class might behave, if you are looking to unit test
that class, I would think you'd absolutely want to know how it works.
Obviously, that need usually goes away when you are accessing that
class from outside of itself.

-Brian
A2b2f4ee23989dc68529baef9cbddcd6?d=identicon&s=25 Julian 'Julik' Tarkhanov (Guest)
on 2006-06-09 18:07
(Received via mailing list)
On 6-jun-2006, at 8:28, Robert MannI wrote:

>
> Any ideas how I can circumvent that?
>
> Or are functional tests really not suited for any kind of logins
> and session work? I don't see why I should move everything to a
> Integration Test just because I added user logins. ]

Looks like you really want a publci method instead of a protected one.

def get_stuff
	# do foo
end

hide_action :get_stuff

This will make it a public method and not a callable action. Another
option would be to just use send to override the access.

@controller.send :logged_in_user # bla bla bla

However, if you want t manage authentication in your tests, it's a
much better idea to actually make your test go through authentication
all by itself, I do it with this method in my test case:


   def with_user(slug, &block)
     passwords = { :john => 'secret' }
     begin
       if @request
         @previous_host  = @request.host
         @request.host = "#{slug}..mydomain.net"
         with_http_auth(slug, passwords[slug.to_sym]) do
           yield
         end
       else
         yield
       end
     ensure # Sometimes the after_filter does not fire - if a
controller throws up, for instance, or the test throws
	# do any cleanup here
       @request.host = @previous_host if @request
     end
   end

Then, to test something with a specific user you do

get :index
assert_response 401

with_user :john do
	get :index
	assert_success
end

You can also make your method supply the actual User object to the
block to compare against it

with_user :john do | john |
	get :index
	assert_success
	assert_equal assigns(:user), john
end

--
Julian 'Julik' Tarkhanov
please send all personal mail to
me at julik.nl
This topic is locked and can not be replied to.