使用Omniauth for Rails测试时无法设置current_user的问题求助
Hey there, let's walk through how to troubleshoot this OmniAuth Google OAuth2 login issue in your integration tests. It's super common to hit this kind of roadblock, so let's break down the key areas to check:
First, make sure you've enabled OmniAuth's test mode and set up a valid mock auth hash in your test helper file (test/test_helper.rb or spec/spec_helper.rb). This is critical because without it, OmniAuth won't skip real OAuth flows in tests.
Here's a standard working config example:
OmniAuth.config.test_mode = true OmniAuth.config.mock_auth[:google_oauth2] = OmniAuth::AuthHash.new({ provider: 'google_oauth2', uid: '123456', info: { email: 'test@example.com', name: 'Test User' }, credentials: { token: 'mock_token', refresh_token: 'mock_refresh_token', expires_at: Time.now + 3600 } })
Pro tip: Double-check that the provider symbol (:google_oauth2) matches exactly what you use in your OmniAuth initializer and routes. If you've shortened it to :google anywhere, the mock won't kick in.
A common mistake is not triggering the OAuth callback directly in tests. Instead of simulating a click on the "Login with Google" button and following redirects, you should hit the callback endpoint directly—this is what triggers SessionsController#create.
For example, in Minitest:
get '/auth/google_oauth2/callback'
Or in RSpec:
get '/auth/google_oauth2/callback'
Also, confirm your routes map this path correctly by running rails routes | grep google in your terminal. You should see a line pointing to sessions#create.
Since you're getting a 302, let's figure out where it's sending the request. Add this line to your test to print the redirect destination:
get '/auth/google_oauth2/callback' puts response.location # In Minitest # Or in RSpec: expect(response).to redirect_to(expected_path)
If it's redirecting back to the login page or an error page, that means either:
- Your OmniAuth mock isn't working (so the auth hash is missing/invalid)
- Your
SessionsController#createlogic is failing to find/create a user and redirecting as a fallback
Add debug logs directly to your create action to confirm if the request is even reaching it. In your controller:
def create Rails.logger.debug "OmniAuth Auth Hash: #{request.env['omniauth.auth']}" Rails.logger.debug "Request reached SessionsController#create!" # Rest of your logic... end
Run your test and check the logs. If you don't see these messages, the request isn't hitting the action at all—so focus on fixing routes or OmniAuth initialization. If you do see them, then the problem is in your logic to set current_user (e.g., not saving the user to the session, or failing to find/create a user from the auth hash).
Check your config/initializers/omniauth.rb file to ensure it's properly configured for all environments (including test). Avoid conditional logic that disables OmniAuth in test mode. A basic valid setup looks like:
Rails.application.config.middleware.use OmniAuth::Builder do provider :google_oauth2, ENV['GOOGLE_CLIENT_ID'], ENV['GOOGLE_CLIENT_SECRET'], scope: 'email,profile' end
Even if your test environment doesn't have the real client ID/secret set, OmniAuth's test mode should override this with your mock data.
If current_user isn't persisting even after the callback, verify your test environment's session setup. In config/environments/test.rb:
Rails.application.configure do # ... config.session_store :cookie_store, key: '_your_app_session' # ... end
You can also directly check the session in your test after the callback:
get '/auth/google_oauth2/callback' puts session[:user_id] # Should show the ID of your test user if everything works
If session[:user_id] is nil, your create action isn't properly storing the user ID in the session.
内容的提问来源于stack exchange,提问作者daveomcd

