Ruby 使用webmock/rspec的存根多部分请求

Ruby 使用webmock/rspec的存根多部分请求,ruby,rspec,sinatra,rest-client,webmock,Ruby,Rspec,Sinatra,Rest Client,Webmock,我已经尝试了一段时间使用webmock存根多部分请求,但没有找到令人满意的解决方案 理想情况下,我希望将请求存根如下: stub_request(:post, 'http://test.api.com').with(:body => { :file1 => File.new('filepath1'), file2 => File.new('filepath2') }) 然而,这似乎不起作用,RSpec抱怨请求没有被存根。打印非存根请求: stub_request(:post,

我已经尝试了一段时间使用webmock存根多部分请求,但没有找到令人满意的解决方案

理想情况下,我希望将请求存根如下:

stub_request(:post, 'http://test.api.com').with(:body => { :file1 => File.new('filepath1'), file2 => File.new('filepath2') })
然而,这似乎不起作用,RSpec抱怨请求没有被存根。打印非存根请求:

stub_request(:post, "http://test.api.com").
     with(:body => "--785340\r\nContent-Disposition: form-data; name=\"file1\"; filename=\"filepath1\"\r\nContent-Type: text/plain\r\n\r\nhello\r\n--785340\r\nContent-Disposition: form-data; name=\"file2\"; filename=\"filepath2\"\r\nContent-Type: text/plain\r\n\r\nhello2\r\n--785340\r\n",
          :headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate', 'Content-Length'=>'664', 'Content-Type'=>'multipart/form-data; boundary=785340', 'User-Agent'=>'Ruby'}).
     to_return(:status => 200, :body => "", :headers => {})
当然,我不能真正遵循这个建议,因为边界是动态生成的。你知道我怎样才能正确地存根这些请求吗

谢谢!
Bruno目前不支持多部分请求。有关更多信息,请查看作者的评论:

我建议你考虑以下一种途径:

  • 不匹配后多部分正文的存根
  • 将请求包装到具有文件路径参数的方法中,并在此方法上设置更细粒度的期望值
  • 在集成测试中使用VCR模拟外部请求

    • 有点晚了,但我会给未来的飞越者和谷歌留下答案

      我也遇到了同样的问题,并将其与Webmock结合使用作为解决方案。快速脏代码应该如下所示(警告:使用activesupport扩展):


      下面是一个使用WebMock和regex匹配多部分/表单数据请求的解决方案,特别适合测试图像上传:

      stub_request(:post, 'sample.com').with do |req|
      
        # Test the headers.
        assert_equal req.headers['Accept'], 'application/json'
        assert_equal req.headers['Accept-Encoding'], 'gzip, deflate'
        assert_equal req.headers['Content-Length'], 796588
        assert_match %r{\Amultipart/form-data}, req.headers['Content-Type']
        assert_equal req.headers['User-Agent'], 'Ruby'
      
        # Test the body. This will exclude the image blob data which follow these lines in the body
        req.body.lines[1].match('Content-Disposition: form-data; name="FormParameterNameForImage"; filename="image_filename.jpeg"').size >= 1
        req.body.lines[2].match('Content-Type: img/jpeg').size >= 1
      
      end
      

      使用
      stub\u请求(:post,'sample.com')的常规WebMock方式也可以只测试头文件。使用(头文件:{'Accept'=>'application/json})
      ,只需在
      with
      子句中不包含任何正文规范。

      这样存根就不会返回任何内容?您想返回什么?仅供参考,现在使用
      Rack::Request.new(env.POST
      似乎比使用
      Rack::Multipart::Parser.new(env.parse)更好
      
      stub_request(:post, 'sample.com').with do |req|
      
        # Test the headers.
        assert_equal req.headers['Accept'], 'application/json'
        assert_equal req.headers['Accept-Encoding'], 'gzip, deflate'
        assert_equal req.headers['Content-Length'], 796588
        assert_match %r{\Amultipart/form-data}, req.headers['Content-Type']
        assert_equal req.headers['User-Agent'], 'Ruby'
      
        # Test the body. This will exclude the image blob data which follow these lines in the body
        req.body.lines[1].match('Content-Disposition: form-data; name="FormParameterNameForImage"; filename="image_filename.jpeg"').size >= 1
        req.body.lines[2].match('Content-Type: img/jpeg').size >= 1
      
      end