Ruby on rails 轨道4+;Rspec:使用restapi'进行自定义身份验证的干式测试;谁的父控制器?
我正在构建一个REST API,并且有一个Ruby on rails 轨道4+;Rspec:使用restapi'进行自定义身份验证的干式测试;谁的父控制器?,ruby-on-rails,ruby,rest,authentication,rspec,Ruby On Rails,Ruby,Rest,Authentication,Rspec,我正在构建一个REST API,并且有一个API::ApicController,它是资源控制器的父级,并保存身份验证代码,以便多个资源可以继承身份验证功能。此控制器本身没有任何操作,因此如何使用rspec测试它?我不能向它发送任何GET请求,我希望保持测试与实际实现一样干燥 class Api::V1::ApiController < ActionController::Base before_action :authenticate protected def authe
API::ApicController
,它是资源控制器的父级,并保存身份验证代码,以便多个资源可以继承身份验证功能。此控制器本身没有任何操作,因此如何使用rspec测试它?我不能向它发送任何GET
请求,我希望保持测试与实际实现一样干燥
class Api::V1::ApiController < ActionController::Base
before_action :authenticate
protected
def authenticate
request_key = request.headers['X-Api-Key']
master_key = Rails.application.secrets.something['api_key']
unless secure_compare(request_key, master_key)
head status: 401
return false
end
end
# extracted from ActiveSupport::MessageVerifier#secure_compare
def secure_compare(a, b)
return false unless a.bytesize == b.bytesize
l = a.unpack "C#{a.bytesize}"
res = 0
b.each_byte { |byte| res |= byte ^ l.shift }
res == 0
end
end
# app/controllers/api/v1/resources_controller.rb
class Api::V1::ResourcesController < Api::ApiController
def index
..
end
# etc etc
end
# spec/controllers/api/v1/resources_controller_spec.rb
context 'Api::ApiController#authenticate' do
describe 'bad key' do
before { request.headers['X-API-KEY'] = 'xyz' }
it 'prevents unauthorized access' do
get 'index', format: :json
expect(response.status).to eq 401
end
end
describe 'good key' do
before { request.headers['X-API-KEY'] = Rails.application.secrets.something['api_key'] }
it 'grants access' do
get 'index', format: :json
expect(response.status).to eq 200
end
end
end
class Api::V1::ApicController
我在我的资源的控制器规范文件中为上面的#authenticate
方法进行了测试,但在那里进行测试感觉不太对,因为a)该方法是Api::ApiController
的一部分,而不是Api::ResourceController
,因为理想情况下,我需要在每个资源的控制器中验证身份验证
我是否需要为该控制器添加一个操作(如
索引
或测试
)以及执行身份验证测试所需的路径?您可以设置一个继承ApicController的抽象控制器(请参阅),但我认为您可能走错了方向
您可以将身份验证逻辑放在关注点或帮助器中,然后将其包括在内,而不是子类化
优点是您可以在测试中直接调用方法,而不是试图设置请求。当涉及到身份验证时,控制器规范可能会很挑剔,因为它们没有实际请求的会话和环境
然后,我将向第一个控制器添加一个功能测试,该控制器实现了验证以测试集成。我不记得了,但我将max的答案标记为正确,因为实际上没有“解决方案”,而且该解决方案似乎是合理的。这可能就是我要的!