我在试图围绕rails控制器编写测试时遇到了一个非常奇怪的问题。
控制器使用RestClient从另一台服务器获取信息。如果第二个服务器返回错误响应,我想将错误消息转发给客户端。
控制器:

def callback_submit
  begin
    response = RestClient.post(...)
    render json: response
  rescue RestClient::BadRequest => e
    render status: :bad_request, json: { error: e.response.body }
  end
end

然后我要做一个rspec测试:
  it 'returns a failure message' do
    stub_request( :post, 'http://...' ).to_return( status: 400, body: 'some error' )

    post :callback_submit

    expect(response.body).to eq({error: 'some error'}.to_json)
  end

现在的问题是rspec输出是:
   expected: "{\"error\":\"some error\"}"
        got: "{\"error\":\"\"}"

奇怪的是我可以把控制器改成一些细节…
  rescue RestClient::BadRequest => e
    error = e.response.body.to_s
    puts error.class
    puts error
    render status: :bad_request, json: { error: error }

哪些输出:
String
some error

   expected: "{\"error\":\"some error\"}"
        got: "{\"error\":\"\"}"

所以puts变量看起来是一个字符串和正确的值,但是error将它变成一个空字符串。
现在真的很奇怪…如果我插入字符串:
  rescue RestClient::BadRequest => e
    error = e.response.body.to_s
    puts error.class
    puts error
    render status: :bad_request, json: { error: "#{error}" }

或者仅仅是:
  rescue RestClient::BadRequest => e
    render status: :bad_request, json: { error: "#{e.response.body}" }

那我的考试就通过了!
起初我认为render不应该是字符串,这就是为什么我在它的e.response.body上打印“string”并称为puts的原因,但这似乎没有改变任何东西。
有人能解释这种奇怪的行为吗?

最佳答案

问了一些ruby的朋友,其中一个发现了问题,但不想在这里发帖。
最后的问题是我们在一个旧的RestClient(1.8)上。In the RestClient 2.0 notes
响应对象现在是字符串的子类,而不是混合在响应功能中的字符串。
响应body和to s现在将返回一个真正的string对象,而不是self。以前,没有一种简单的方法可以获得真正的字符串响应,而不是包含abstractresponse的frankenstein响应字符串对象。
所以在我使用的旧版本中,e.response最终变成了一个奇怪的字符串混合mashup,而render似乎并不喜欢它。
插值再次将其转换为一个真正的ruby字符串。

关于ruby-on-rails - Rails不会渲染RestClient异常主体,除非我对其进行插值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38443953/

10-08 22:58