rspec

时间:2016-11-15 13:35:04

标签: ruby-on-rails rspec net-http

我是在其他网站上传图片文件,他们也为此提供了上传API。

文件上传过程分为两部分

  1. 创建图片ID(POST)
  2. 上传图片(PUT)
  3. 当我创建图片ID时,它会在响应中返回id。为此,我添加了以下实现此功能的方法。

      def create_image_id
        response = create_via_api(data)
        # we get response in the following format
        # #<Net::HTTPCreated 201 Created readbody=true>
        find_id_from_response(response)
      end
    
      def create_via_api(data)
        access_token.post(IMAGE_CREATE_URL, data, 'Accept' => ACCEPT_HEADER)
      end
    
      # We are getting id from the response headers in the following format
      # location: SITE_URL/imageResources/5ac2acb2
      def find_id_from_response(response)
        id = response.to_hash['location'].first
        return unless id
        id.split('/').last.chomp
      end
    

    现在我必须为create_image_id方法编写测试用例。

    对于测试用例,与第三方API进行通信并不是一个好习惯。所以我在POST响应中说,

      allow(Image).to receive(:find_id_from_response).and_return('1234')
    

    因此它总是将id返回123,以便我可以将测试用例写为

      expect(image. create_image_id).to eq 1234
    

    正如您所见,find_id_from_response取参数(#)。

    注意:这是响应的标题

      [36] pry(#)> response.to_hash
      {
      "content-type"=>["text/plain"],
      "x-frame-options"=>["SAMEORIGIN"],
      "location"=>["www.example.com/imageResources/cd87b8ef"],
      "vary"=>["Accept-Encoding"],
      "cache-control"=>["max-age=0, no-cache"],
      "pragma"=>["no-cache"],
      "date"=>["Tue, 15 Nov 2016 12:01:56 GMT"],
      "connection"=>["close"]
      }
    

    我尝试了以下

      [28] pry()> Net::HTTPCreated.new(1, 201, 'Created')
      => #<Net::HTTPCreated 201 Created readbody=false>
      [29] pry()> a = Net::HTTPCreated.new(1, 201, 'Created')
      => #<Net::HTTPCreated 201 Created readbody=false>
      [30] pry()>)> a.to_hash
      => {}
    

    它返回空哈希。那么如何存根create_via_api的响应?

    让我知道你需要的任何东西。

2 个答案:

答案 0 :(得分:1)

I don't think有一种简单的方法可以返回一个http响应对象。因此,您可以使用rspec mocks

response_hash = {
  "content-type"=>["text/plain"],
  "x-frame-options"=>["SAMEORIGIN"],
  "location"=>["www.example.com/imageResources/cd87b8ef"],
  "vary"=>["Accept-Encoding"],
  "cache-control"=>["max-age=0, no-cache"],
  "pragma"=>["no-cache"],
  "date"=>["Tue, 15 Nov 2016 12:01:56 GMT"],
  "connection"=>["close"]
}
response_double = double
allow(response_double).to receive(:to_hash).and_return(response_hash)
allow(instance).to receive(:create_via_api).and_return(response_double)
expect(instance.create_via_api("data").to_hash['content-type']).to eq(["text/plain"])

另一种选择是使用记录和保存api调用的内容进行测试,并对所有后续测试过程使用缓存响应,如vcr

答案 1 :(得分:1)

尝试使用 add_field http://apidock.com/ruby/Net/HTTPHeader/add_field)。它为命名的头字段添加一个值,而不是替换它的值。

2.0.0-p643 :533 > response = Net::HTTPCreated.new('HTTP/2', 201, 'Created')
 => #<Net::HTTPCreated 201 Created readbody=false> 
2.0.0-p643 :534 > response.add_field('vary', 'Accept-Encoding')
 => ["Accept-Encoding"] 
2.0.0-p643 :535 >     response.add_field('cache-control', 'max-age=0, no-cache')
 => ["max-age=0, no-cache"] 
2.0.0-p643 :536 >     response.add_field('pragma', 'no-cache')
 => ["no-cache"] 
2.0.0-p643 :537 > response.to_hash
 => {"vary"=>["Accept-Encoding"], "cache-control"=>["max-age=0, no-cache"], "pragma"=>["no-cache"]} 
2.0.0-p643 :538 >