Luca G. Soave
Luca G. Soave

Reputation: 12699

Stubbing protected or private methods with Minitest

How can I stub private/protected methods to be passed in functional controller tests?

Having the following code for example:

app/controllers/sessions_controller.rb

class SessionsController < ApplicationController
  def create
    @user = User.from_omniauth(auth_hash)
    reset_session
    session[:user_nickname] = @user.nickname

    if @user.email.blank?
      redirect_to edit_user_path(@user.nickname), :alert => "Please enter your email address."
    else
      redirect_to show_user_path(@user.nickname), :notice => 'Signed in!'
    end
  end

  private

  def auth_hash
    request.env['omniauth.auth']
  end
end

I tried the following :

test/controllers/sessions_controller_unit_test.rb

require 'test_helper'
class SessionsControllerTest < ActionController::TestCase

  test "should create new user" do

    # get the same 'request.env['omniauth.auth'] hash
    auth_h = OmniAuth.config.mock_auth[:github] 

    # but auth_hash is never passed in User.find_or_create_from_auth_hash(auth_hash) 
    # method, which result to be nil breaking the User model call
    get :create, provider: 'github', nickname: 'willishake', auth_hash: auth_h

    assert_redirected_to show_user_path(nickname: 'willishake')
    assert_equal session[:user_id], "willishake"
  end
end

but when get :create (the test method) calls the model User.find_or_create_from_auth_hash(auth_hash), auth_hash is nil, breaking the functional test.

So what's the right way to stub auth_hash private method and passing to User model call User.from_omniauth(auth_hash) ?

UPDATE: after blowmage suggestion, it works like the following:

require 'test_helper'
class SessionsControllerTest < ActionController::TestCase

  def setup
    request.env['omniauth.auth'] = OmniAuth.config.mock_auth[:github]
  end

  test "should create new user" do
    get :create, provider: 'github', nickname: 'willishake'

    assert_equal session[:user_id], "willishake"
    assert_redirected_to show_user_path(nickname: 'willishake')
  end
end

Upvotes: 1

Views: 2144

Answers (1)

blowmage
blowmage

Reputation: 8984

Try this:

# set the request.env['omniauth.auth'] hash
auth_h = OmniAuth.config.mock_auth[:github]
request.env['omniauth.auth'] = auth_h

Upvotes: 2

Related Questions