将 Omniauth 用于 Rails 我无法在 运行 我的测试时设置 current_user

Using Omniauth for Rails I can't get current_user set when running my test

我正在尝试为我的应用程序构建集成测试,以便为用户执行 "sign in" 功能。我目前正在使用 omniauth-google-oauth2 gem。一切似乎都运行良好,除了我从未从 sign_in 中获取我的 "current_user" 对象集。 sign_in 执行并 returns 一条 302 消息,并且永远不会通过 sessions_controller#create 操作。谁能给我指出正确的方向,或者让我知道我是否错误地设置了 OmniAuth 测试?

test/integration/blog_flow_test.rb

require 'test_helper'

class BlogFlowTest < ActionDispatch::IntegrationTest
  include SignInHelper

  test "user can see the welcome page" do
    get "/"
    assert_select "h1#title", "Donut with my Coffee"
    assert_select "a#sign_in", "Sign in with Google"
  end

  test "author can create an article" do
    sign_in(admin=true)
    get "/posts/new"
    assert_response :success
  end

end

test/controllers/sessions_controller_test.rb

require 'test_helper'

class SessionsControllerTest < ActionDispatch::IntegrationTest

  setup do
    Rails.application.env_config["omniauth.auth"] = OmniAuth.config.mock_auth[:google_oauth2]
  end

  test "should get create" do
    get sessions_create_url
    assert_response :success
  end

  test "should get destroy" do
    get sessions_destroy_url
    assert_response :success
  end

end

app/controllers/sessions_controller.rb

class SessionsController < ApplicationController
  def create
    user = User.from_omniauth(request.env["omniauth.auth"])
    session[:user_id] = user.id
    redirect_to root_path
  end

  def destroy
    session[:user_id] = nil
    redirect_to root_path
  end
end

test/test_helper.rb

require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'

class ActiveSupport::TestCase

  fixtures :all
  OmniAuth.config.test_mode = true

  module SignInHelper

      def sign_in(admin=true)
        set_mock_auth(admin)        
        post "/auth/google_oauth2"
      end

      def set_mock_auth(admin)
        if admin
            OmniAuth.config.mock_auth[:google_oauth2] = 
                OmniAuth::AuthHash.new(auth_object_for_existing_user)
        else
            OmniAuth.config.mock_auth[:google_oauth2] = 
                OmniAuth::AuthHash.new(auth_object_for_new_user)
        end
      end

      private

        def auth_object_for_existing_user
            auth = {
              provider: "google_oauth2",
              uid: "123456789",
              info: {
                email: "papasmurf@example.com",
                first_name: "Papa",
                last_name: "Smurf"
              },
              credentials: {
                token: "abcdefg12345",
                refresh_token: "12345abcdefg",
                oauth_expires_at: DateTime.now
              }
            }
          end

          def auth_object_for_new_user
            auth = {
              provider: "google_oauth2",
              uid: "1337",
              info: {
                email: "drjones@example.com",
                first_name: "Indiana",
                last_name: "Jones"
              },
              credentials: {
                token: "abc123",
                refresh_token: "123abc",
                oauth_expires_at: DateTime.now
              }
            }
          end
    end
end

app/controllers/application_controller.rb

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  helper_method :current_user

  def current_user
    if session[:user_id]
        @current_user ||= User.find(session[:user_id])
    end
  end
end

您可以按如下所示对经过身份验证的用户进行存根:

before do
  let(:user) { build(:user) }
  allow(controller).to receive_messages(current_user: user)
end