diff --git a/changelogs/unreleased/34549-extract-devise-mappings-into-helper.yml b/changelogs/unreleased/34549-extract-devise-mappings-into-helper.yml
new file mode 100644
index 0000000000000000000000000000000000000000..e843bbac23970bce37a704591157c7b6a0f7f9a6
--- /dev/null
+++ b/changelogs/unreleased/34549-extract-devise-mappings-into-helper.yml
@@ -0,0 +1,4 @@
+---
+title: Extract "@request.env[devise.mapping] = Devise.mappings[:user]" to a test helper
+merge_request: 12742
+author: Jacopo Beschi @jacopo-beschi
diff --git a/spec/controllers/sessions_controller_spec.rb b/spec/controllers/sessions_controller_spec.rb
index bf922260b2f7a61d2a82767b00a5851f698be114..e17d5639d7b0c967488248a5f425741bf9c9b86a 100644
--- a/spec/controllers/sessions_controller_spec.rb
+++ b/spec/controllers/sessions_controller_spec.rb
@@ -1,9 +1,11 @@
 require 'spec_helper'
 
 describe SessionsController do
+  include DeviseHelpers
+
   describe '#new' do
     before do
-      @request.env['devise.mapping'] = Devise.mappings[:user]
+      set_devise_mapping(context: @request)
     end
 
     context 'when auto sign-in is enabled' do
@@ -34,7 +36,7 @@ describe SessionsController do
 
   describe '#create' do
     before do
-      @request.env['devise.mapping'] = Devise.mappings[:user]
+      set_devise_mapping(context: @request)
     end
 
     context 'when using standard authentications' do
@@ -257,7 +259,7 @@ describe SessionsController do
 
   describe '#new' do
     before do
-      @request.env['devise.mapping'] = Devise.mappings[:user]
+      set_devise_mapping(context: @request)
     end
 
     it 'redirects correctly for referer on same host with params' do
diff --git a/spec/features/oauth_login_spec.rb b/spec/features/oauth_login_spec.rb
index 42764e808e6768e589bef987c59570fbbc36c339..0064c9ef25e11b49113409b4d8e102b013e600a0 100644
--- a/spec/features/oauth_login_spec.rb
+++ b/spec/features/oauth_login_spec.rb
@@ -1,6 +1,8 @@
 require 'spec_helper'
 
 feature 'OAuth Login', js: true do
+  include DeviseHelpers
+
   def enter_code(code)
     fill_in 'user_otp_attempt', with: code
     click_button 'Verify code'
@@ -8,7 +10,7 @@ feature 'OAuth Login', js: true do
 
   def stub_omniauth_config(provider)
     OmniAuth.config.add_mock(provider, OmniAuth::AuthHash.new(provider: provider.to_s, uid: "12345"))
-    Rails.application.env_config['devise.mapping'] = Devise.mappings[:user]
+    set_devise_mapping(context: Rails.application)
     Rails.application.env_config['omniauth.auth'] = OmniAuth.config.mock_auth[provider]
   end
 
diff --git a/spec/javascripts/fixtures/u2f.rb b/spec/javascripts/fixtures/u2f.rb
index c9c0b89123766f4a83f535226955ac36e725b964..e3d7986f2cf48c71b0f61118bbf28cd2bb005c13 100644
--- a/spec/javascripts/fixtures/u2f.rb
+++ b/spec/javascripts/fixtures/u2f.rb
@@ -10,10 +10,12 @@ context 'U2F' do
   end
 
   describe SessionsController, '(JavaScript fixtures)', type: :controller do
+    include DeviseHelpers
+
     render_views
 
     before do
-      @request.env['devise.mapping'] = Devise.mappings[:user]
+      set_devise_mapping(context: @request)
     end
 
     it 'u2f/authenticate.html.raw' do |example|
diff --git a/spec/support/devise_helpers.rb b/spec/support/devise_helpers.rb
new file mode 100644
index 0000000000000000000000000000000000000000..890a2d9d2878950092091fe979bd993b1d14847d
--- /dev/null
+++ b/spec/support/devise_helpers.rb
@@ -0,0 +1,14 @@
+module DeviseHelpers
+  # explicitly tells Devise which mapping to use
+  # this is needed when we are testing a Devise controller bypassing the router
+  def set_devise_mapping(context:)
+    env =
+      if context.respond_to?(:env_config)
+        context.env_config
+      elsif context.respond_to?(:env)
+        context.env
+      end
+
+    env['devise.mapping'] = Devise.mappings[:user] if env
+  end
+end
diff --git a/spec/support/login_helpers.rb b/spec/support/login_helpers.rb
index b410a652126234621fac87ca39d08cfc114877f4..701de9c8c19f7e2d0eba1772c5a730f7bae0c198 100644
--- a/spec/support/login_helpers.rb
+++ b/spec/support/login_helpers.rb
@@ -1,4 +1,6 @@
 module LoginHelpers
+  include DeviseHelpers
+
   # Internal: Log in as a specific user or a new user of a specific role
   #
   # user_or_role - User object, or a role to create (e.g., :admin, :user)
@@ -106,7 +108,7 @@ module LoginHelpers
   end
 
   def stub_omniauth_saml_config(messages)
-    Rails.application.env_config['devise.mapping'] = Devise.mappings[:user]
+    set_devise_mapping(context: Rails.application)
     Rails.application.routes.disable_clear_and_finalize = true
     Rails.application.routes.draw do
       post '/users/auth/saml' => 'omniauth_callbacks#saml'