访问请求规范中的请求对象

Ped*_*nto 9 ruby rspec ruby-on-rails rspec-rails ruby-on-rails-4

如何在请求规范上执行请求之前设置请求标头?

我正在移动控制器规范,以使用Rails在我的API上请求规范.我坚持的一件事是我无法访问request允许请求的对象.

在我的控制器规格上,我可以访问我创建的方法,该方法对特定用户进行签名:

def sign_in(user)
  token = user.api_keys.first.token
  # note the request object being used in the next line
  request.env["HTTP_AUTHORIZATION"] = ActionController::HttpAuthentication::Token.encode_credentials(token)
end
Run Code Online (Sandbox Code Playgroud)

这在控制器规格上工作正常,我可以安全地做到:

before { sign_in(user) }
it { post :endpoint, params }
Run Code Online (Sandbox Code Playgroud)

但是根据请求规范,该request对象不可用.如果我尝试:

before { sign_in(user) }
it { post "/api/endpoint", params }
Run Code Online (Sandbox Code Playgroud)

我接受request了我的助手方法nil.

我知道我能做到:

it { post "/api/endpoint", {"HTTP_AUTHORIZATION" => ... } }
Run Code Online (Sandbox Code Playgroud)

但这在规范中看起来很混乱,特别是与控制器规格相比.

我已ActionDispatch::TestRequest::DEFAULT_ENV按照这个答案的建议尝试使用,但它也没有用(我得到了401).

Sam*_*Sam 4

如果您尚未使用Rack::Test此功能,那么您应该使用。Rack::Test比 Capybara 更适合测试 API 请求。它可以在您的rspec/spec_helper.rb

RSpec.configure do |config|
  # ...
  config.include Rack::Test::Methods
end
Run Code Online (Sandbox Code Playgroud)

当您配置为使用 Rack::Test 时,您可以在请求之前设置标头,如下所示:

it 'POST /api/enpoint authenticates successfully' do
  header 'Authorization', '...'
  post "/api/endpoint", params
  expect(last_response).to be_ok
end
Run Code Online (Sandbox Code Playgroud)

这可以在您的控制器中作为 访问request.headers['HTTP_AUTHORIZATION']

该方法的源代码可以在这里找到 - https://github.com/brynary/rack-test/blob/master/lib/rack/test.rb#L127-L141