I'm writing an RSpec request spec, which looks roughly like (somewhat shortened for brevity):
describe 'Items', type: :request do
describe 'GET /items' do
before do
allow_any_instance_of(ItemsController).to receive(:current_user).and_return(user)
get '/items'
@parsed_body = JSON.parse(response.body)
end
it 'includes all of the items' do
expect(@parsed_body).to include(item_1)
expect(@parsed_body).to include(item_2)
end
end
end
The controller looks like:
class ItemsController < ApplicationController
before_action :doorkeeper_authorize!
def index
render(json: current_user.items)
end
end
As you can see, I'm trying to stub doorkeeper's current_user
method.
The tests currently pass and the controller works as expected. My question is about the line:
allow_any_instance_of(ItemsController).to receive(:current_user).and_return(user)
I wrote this line based on the answers in How to stub ApplicationController method in request spec, and it works. However, the RSpec docs call it a "code smell" and rubocop-rspec
complains, "RSpec/AnyInstance: Avoid stubbing using allow_any_instance_of
".
One alternative would be to get a reference to the controller and use instance_double()
, but I'm not sure how to get a reference to the controller from a request spec.
How should I write this test avoid code smells / legacy testing approaches?