RSpec: how to stub inherited method current_user (w/o Devise)?
Also works
user = create(:user) #FactoryBot
allow(controller).to receive(:current_user).and_return(user)
I run into the same problem with a legacy Rails 4 app and based my solution on this test case of Rspec Views.
First define a helper that will define the missing helper method in the controller instance
# /spec/support/concerns/view_helper.rb
module ViewHelper
def include_current_user_helper(&block)
controller.singleton_class.class_eval do
define_method :current_user, &block
helper_method :current_user
end
end
end
Then configure Rspec to include it in all the view helpers
# spec/rails_helper.rb
# ...
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
RSpec.configure do |config|
# ...
config.include ViewHelper, type: :view
end
And in the view specs it is called like this
RSpec.describe 'something' do
let!(:user) { FactoryGirl.create(:user) } # Note the "!" there
before { include_current_user_helper { user } }
# do stuff
end
Note: the call to let
with bang is important as content inside the block will be executed lazily, outside of the test scope, and user will be nill if not
For me, worked with:
before { controller.stub!(:current_user).and_return(user) }
If you are doing unit testing of your controller you can simply stub your current_user
in a before block, like this:
let(:user) { ... }
# RSpec version <= 2 syntax:
before { controller.stub(:current_user) { user } }
# RSpec version >= 3 syntax:
before { allow(controller).to receive(:current_user) { user } }
If you are doing feature or request testing, I advise you to perform a real log-in by creating a user in your database, then passing through your log-in page with this user credentials
Here you seem to be doing a feature test, you should write a helper that perform the creation of the user record and go through the log-in.
Additionally in feature testing to gain a lot of time while running your test, do not hesitate to group your assertions in the same block. Clearly, instead of:
it { should have_button('Submit')}
it { should have_link('Cancel')}
it { should have_content(user.fname+"\'s profile")}
You can write
it 'check links and content' do
should have_button('Submit')
should have_link('Cancel')
should have_content(user.fname+"\'s profile")
end
That will avoid to generate several session of your feature environment, and also to log-in several times