在Sinatra中使用二进制数据模拟一个post请求

时间:2017-09-19 13:55:48

标签: ruby unit-testing sinatra rack-test

我的Sinatra应用程序中有一个端点,它将接收二进制数据作为正文的一部分。发送数据的另一个应用程序将有一个如下所示的法拉第请求:

    connection = Faraday.new(url: "https://example.com/post_data") do |conn|
      conn.request :multipart
      conn.adapter :net_http
      conn.headers['Content-Type'] = 'octet/stream'
    end

    @response ||= connection.post do |req|
      req.params = { :host => host,
                     :verification => "false"}
      req.body = my_base64_encoded_binary
    end

然后,在Sinatra中,我将有一个接收这些请求参数和二进制数据的端点,并将其传递给模型,如下所示:

post '/post_data' do
  request.body.rewind
  payload = request.body.read

  raise Sinatra::NotFound unless payload and params[:host]
  output = MyOutput.new(params, payload)

  content_type 'application/json'
  body output.data
end

当我尝试使用Rack::Test帮助程序测试此端点时,我最终陷入了一种奇怪的境地。我似乎无法创建正确的模拟,以便正确测试此端点。基于PostMan的一些手动测试,我非常确定我的端点是否正常工作。这只是阻碍我的考验。这是规范:

 it "should return a json response" do
    post(url, :host => host, :verification => "false") do |req|
      req.body = [my_binary]
      req.content_type = "application/octet-stream"
    end

    expect(last_response.status).to eq(200)
    expect(last_response.content_type).to eq("application/json")
  end

当我检查传入请求在测试中的样子时,它不包含正确的主体。 params已正确设置为我设置的hostverification设置,但正文也设置为参数(通过payload = request.body.read检查)而不是二进制。< / p>

是否有不同的方法来设置模拟以便正确地将二进制文件设置为请求的主体,并且参数仍然正确地设置为请求参数?

1 个答案:

答案 0 :(得分:0)

答案是发布正文的唯一方法是我在机架测试助手中添加参数。我需要使用params并将它们移动到请求中URL的查询字符串中,然后仅将二进制文件作为body请求的post添加到测试帮助程序中。

  let(:url) { "http://example.com/post_data?host=>#{host}&verification=#{verification}" } 
  it "should return a json response" do
    post(url, my_binary)

    expect(last_response.status).to eq(200)
    expect(last_response.content_type).to eq("application/json")
  end