如何防止哈希转义字符串?

时间:2013-09-19 19:54:49

标签: ruby-on-rails ruby

我有以下代码生成用于测试内部Restful API身份验证的哈希。

问题是生成的哈希值正在返回转义值。

json_headers方法应返回如下内容:

{"Authorization"=>"Basic ZnBfZXJwOllrdGh4aHRSZTZWM1d1d09oeVlmcW0xTg==", "Accept"=>"application/json"} 

但是回来了:

{\"Authorization\"=>\"Basic ZnBfZXJwOllrdGh4aHRSZTZWM1d1d09oeVlmcW0xTg==\\n\", \"Accept\"=>\"application/json\"}

有没有人知道从Ruby哈希返回原始键/值的简单方法?

以下是代码:

module ERP
  class CustomersMock

    def json_headers
      authorization_hash.merge("Accept"=>"application/json")
    end

    def authorization_hash 
      {"Authorization" => "Basic #{base64_user_pass}"}
    end

    def user_pass
       # user:password
       [ ERP_CONF['user'], ERP_CONF['password'] ].join(':')
    end

    def base64_user_pass
      Base64.encode64(user_pass)
    end

    def add(customer)
      customers << customer
    end        

    def customers
      []
    end         

    def run
      ActiveResource::HttpMock.respond_to do |mock|
        customers.each do |customer|
          mock.get "/customers/#{customer.id}.json", json_headers, customer.to_json
        end
      end
    end
  end
end

出于某种原因,如果我对头文件哈希硬编码,它们可以工作,但如果我调用json_headers方法,respond_to块会将它们转换为字符串并转义值。

这是rspec失败:

Could not find a response recorded for <GET: /api/customers/1011.json [{"Authorization"=>"Basic ZnBfZXJwOllrdGh4aHRSZTZWM1d1d09oeVlmcW0xTg==", "Accept"=>"application/json"}] ()> - Responses recorded are: ["<GET: /api/customers/1011.json [{\"Authorization\"=>\"Basic ZnBfZXJwOllrdGh4aHRSZTZWM1d1d09oeVlmcW0xTg==\\n\", \"Accept\"=>\"application/json\"}] ()>"]

2 个答案:

答案 0 :(得分:3)

首先,转码引号有点令人困惑。我猜你是从一个REPL如IRB或Pry测试的。您的方法实际上包含普通双引号 - 它们仅被转义为输出,因为双引号已用于表示字符串的开头和结尾。这意味着当您确实想要在字符串中存储双引号字符"时,您需要键入"\"",因为如果您键入""",您实际上将以第二个字符串结束字符串"。您可以通过使用puts实际打印字符串来查看“真正”包含的字符串。让我用一个例子证明这一点:

require 'json'

h = {a: 123, b: 456}

h.to_json
#=> "{\"a\":123,\"b\":456}"       # note the escaped double quotes

puts h.to_json
# {"a":123,"b":456}               # when printed, quotes are no longer escaped

double_quote_1 = '"'              # another way to store " in a string
double_quote_2 = "\""
double_quote_1 == double_quote_2  # both have the same contents, a single "
#=> true

json1 = '{"a":123,"b":456}'       # less confusing way of writing the json from above
json2 = "{\"a\":123,\"b\":456}"
json1 == json2
#=> true

答案 1 :(得分:0)

这不是逃避问题。我认为这是基于rspec失败的测试输出:

Could not find a response recorded for 
<GET: /api/customers/1011.json [{"Authorization"=>"Basic ZnBfZXJwOllrdGh4aHRSZTZWM1d1d09oeVlmcW0xTg==", "Accept"=>"application/json"}] ()> 

- Responses recorded are: [
"<GET: /api/customers/1011.json [{\"Authorization\"=>\"Basic ZnBfZXJwOllrdGh4aHRSZTZWM1d1d09oeVlmcW0xTg==\\n\", \"Accept\"=>\"application/json\"}] ()>"
]

看起来唯一的区别是header hash被转义为一个而不是另一个。

但是,它没有转义在“授权”值结束时结束的行,因此修复是剥离值:

def base64_user_pass
  Base64.encode64(user_pass).strip
end