Chuck Logan Lim Chuck Logan Lim - 7 months ago 21
Ruby Question

Including SessionsHelper in RailsTutorial.org test_helper: why not?

In railstutorial.org, Listing 8.23:

ENV['RAILS_ENV'] ||= 'test'
.
.
.
class ActiveSupport::TestCase
fixtures :all

# Returns true if a test user is logged in.
def is_logged_in?
!session[:user_id].nil?
end
end


suggests creating a duplicate method to check whether the current user is logged in (having already defined such a method in
sessions_helper.rb
) for use in testing. However, I was wondering why the author chose to do this in the first place. He explains his reasoning as such:


To test the behavior from Listing 8.22, we can add a line to the test from Listing 7.26 to check that the user is logged in. It’s helpful in this context to define a is_logged_in? helper method to parallel the logged_in? helper defined in Listing 8.15, which returns true if there’s a user id in the (test) session and false otherwise (Listing 8.23). (Because helper methods aren’t available in tests, we can’t use the current_user as in Listing 8.15, but the session method is available, so we use that instead.) Here we use is_logged_in? instead of logged_in? so that the test helper and Sessions helper methods have different names, which prevents them from being mistaken for each other.


However, in an exercise from Chapter 5, the author writes code including
ApplicationHelper
in its test suite (see Listing 5.37):

ENV['RAILS_ENV'] ||= 'test'
.
.
.
class ActiveSupport::TestCase
fixtures :all
include ApplicationHelper
.
.
.
end


When I included
SessionsHelper
and ran my tests using code from that helper module, my tests still passed. I was wondering if the author chose to forgo including
SessionsHelper
in the code because that technique was used in an exercise (and thus better off applied elsewhere) or if actually including
SessionsHelper
to the test suite is a Bad Thing for some reason or another. Any insights to this?

Answer

After going through Chapter 8, I found that testing for whether the user is logged in using the code from logged_in? (i.e., !current_user.nil?) won't work for tests somehow, so the method current_user doesn't actually work (i.e., somehow it always returns true). Though I don't know exactly why; I'm basing it off of this quote:

(Because helper methods aren’t available in tests, we can’t use the current_user as in Listing 8.15, but the session method is available, so we use that instead.)

So essentially using the current_user method in tests won't work because it's not available in tests? (I thought I included them in test_helper.rb with the line include SessionsHelper, though.

This is my answer for now. It would be great if someone more knowledgable than me could confirm the inner workings of this.

EDIT: Okay so I think it's because the current_user method uses @current_user ||= User.find_by(id: user_id) but the User database is different between development and testing.

Comments