Search code examples
rubyrspecruby-on-rails-3.1rspec-railsrailstutorial.org

RSpec test creation, Hartl's tutorial => RoR 3.1. CH10: Calling test_sign_in or post :create, :session => @attr from users_controller_spec


I'm trying to walk through Hartl's Ruby on Rails tutorial whilst upgrading his examples to Rails 3.1 by studying railscasts and stackoverflow posts because I like learning stuff the hard way. My version includes has_secure_password.

Unfortunately I've hit a bump. For some reason I can't call test_sign_in (@user) from users_controller_spec.rb. I can let the tests pass by cheating and using post :create, :user => @attrbecause this method will also call sign_in. Moreover, I'm fairly certain that this is mainly an RSpec related problem as all the failing tests do in fact work when trying the scenario's out in the browser.

The test does seem to call post :create, :session => @attr but fails to actually log in. I thought this might have something to do with my factory; but I don't think there's anything wrong with it. After trying for hours I've given up hope and turn to you guys. It'd be great if you could help me out!

failing tests in users_controller_spec.rb

describe "PUT 'update'" do

    before(:each) do
      @user = Factory(:user)
       @attr = { :email => @user.email, :password => @user.password }
       post :create, :session => @attr
      #sign_in(@user)
    end

    describe "failure" do

      before(:each) do
        @attr = { :email => "", :name => "", :password => "",
                  :password_confirmation => "" }
      end

      it "should render the 'edit' page" do
       put :update, :id => @user, :user => @attr
       response.should render_template('edit')
      end

sessions_controller.rb create method

class SessionsController < ApplicationController

  def create
      user = User.find_by_email(params[:session][:email]) 
      if user && user.authenticate(params[:session][:password])
        if params[:remember_me]  
          sign_in_permanent (user)
        else
          sign_in (user)
        end
          redirect_to user, :notice => "Logged in!"
      else
          flash.now[:error] = "Invalid email or password"
          @title = "Sign in"
          render 'new'
        end
    end

Note: I realize I'm not adhering to DRY here, unfortunately I don't know how to pass parameters to the sign_in method yet :(

sessions_helper.rb sign_in method

def sign_in(user)
    cookies[:remember_token] = user.remember_token
    current_user = user
    @current_user = user
end

If I'm not mistaken this is all the code that's involved in this 'bug'. Obviously I could post far more code but that probably won't help anything. If this assumption is wrong, please let me know and I'll post whatever is necessary.


Solution

  • Figured out how to do this. Because of the different controllers these tests need to be converted to integration tests.

    See the following links for a dense overview of integration tests:

    http://relishapp.com/rspec/rspec-rails/docs/request-specs/request-spec http://api.rubyonrails.org/classes/ActionDispatch/IntegrationTest.html