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

11

在请求规范(request spec)执行请求之前,如何设置请求头(request headers)?

我正在使用Rails将控制器规范(controller specs)转移到请求规范中。我遇到的一个问题是我无法访问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 spec)中,request对象是不可用的。 如果我尝试:

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

我的帮助方法中的requestnil

我知道我可以这样做:

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

但是与控制器规范相比,这似乎是很多杂乱的内容。

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

2个回答

4

如果你还没有使用Rack::Test,那么你应该使用它。与Capybara相比,Rack::Test更适用于测试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


RSpec文档中有没有指定这个? - Eric Francis

-1
如果您在请求规范中使用capybara,我猜您可以像这里建议的那样设置标头,但最好通过HTML表单或任何其他身份验证应用程序的方式执行真正的登录,因为请求规范比控制器更高级,这就是为什么它们通常不允许您手动设置标头、cookie和其他低级别内容的原因。

这是一个API,仅输出JSON,而不是最终用户正在交互的内容。 - Pedro Nascimento

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接