我正在编写一个RSpec request spec,它大致看起来像(为了简短起见,略作缩写):
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控制器看起来像这样:
class ItemsController < ApplicationController
before_action :doorkeeper_authorize!
def index
render(json: current_user.items)
end
end正如您所看到的,我正在尝试存根doorkeeper的current_user方法。
测试目前已通过,控制器按预期工作。我的问题是关于这条线:
allow_any_instance_of(ItemsController).to receive(:current_user).and_return(user)我根据How to stub ApplicationController method in request spec中的答案写了这一行,它很有效。然而,the RSpec docs call it a "code smell"和rubocop-rspec抱怨说,"RSpec/AnyInstance: Avoid stubbing using allow_any_instance_of“。
一种替代方法是获取对控制器的引用并使用instance_double(),但我不确定如何从请求规范中获取对控制器的引用。
我应该如何编写此测试避免代码气味/遗留测试方法?
发布于 2020-03-20 01:30:01
你应该是去度假的。
我认为正确的方法是在请求规范中尽可能避免存根,doorkeeper需要一个令牌来授权,所以我会这样做:
describe 'Items', type: :request do
describe 'GET /items' do
let(:application) { FactoryBot.create :oauth_application }
let(:user) { FactoryBot.create :user }
let(:token) { FactoryBot.create :access_token, application: application, resource_owner_id: user.id }
before do
get '/items', access_token: token.token
@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下面是这些工厂可能是什么样子的some examples。
最后,非常好的点数!
https://stackoverflow.com/questions/60752058
复制相似问题