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

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

我正在移动控制器规范以使用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 

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

 before { sign_in(user) } it { post :endpoint, params } 

但是在请求规范中, request对象不可用。 如果我尝试:

 before { sign_in(user) } it { post "/api/endpoint", params } 

我的帮助方法requestnil

我知道我能做到:

 it { post "/api/endpoint", {"HTTP_AUTHORIZATION" => ... } } 

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

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

如果你还没有使用Rack::Test那么你应该这样做。 Rack::Test比Capybara更适合测试API请求。 它可以在rspec/spec_helper.rb配置

 RSpec.configure do |config| # ... config.include Rack::Test::Methods end 

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

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

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

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

如果你使用capybara作为请求规范,我猜你可以设置像这里建议的标题,但是最好通过HTML表单执行真正的登录或者在你的应用程序中进行身份validation的方式,因为请求规范的级别高于控制器,这就是为什么他们通常不允许你手动设置标题,cookie和其他低级别的东西。