3

I don't have much experience with stubbing and am having issues with requests to Braintree using webmock and braintree-rails.

spec/spec_helper.rb

RSpec.configure do |config|
  config.include(ConnectionHelper)

  config.before(:each) do
    stub_request(:post, /.*braintree.*/).
    with(braintree_hash).to_return(gzipped_response)
  end
end

spec/support/connection_helper.rb

def gzipped_response
  {
    status: 200,
    body: "\u001F\x8B\b\0:\x87GU\0\u0003\u0003\0\0\0\0\0\0\0\0\0",
    headers: {}
  } 
end

def braintree_hash
  { :body => /.*/,
    :headers => {'Accept'=>'application/xml', 'Content-Type'=>'application/xml',
    'User-Agent'=>'Braintree Ruby Gem 2.42.0 (braintree-rails-1.4.0)',
    'X-Apiversion'=>'4'}
  }
end

Rspec error:

2) Content: when ordering content show page has relevant information 
     Failure/Error: click_button "Order"
     Braintree::UnexpectedError:
       expected a gzipped response
     # ./app/classes/payment.rb:13:in `generate_token'
     # ./app/controllers/posts_controller.rb:44:in `pay'
     # ./spec/features/content_spec.rb:251:in `block (4 levels) in <top (required)>'

I'm trying to test the page, not the payments themselves, however when rendering the page a token needs to be retrieved first and so I'm getting this error.

How would I go about faking a gzipped response, or alternatively skip anything to do with Braintree requests in my tests?

app/controllers/posts_controller.rb

def pay
  @post = Post.find(params[:id])
  @client_token = Payment.new(current_user).generate_token
end

app/classes/payment.rb

class Payment    
  def initialize(customer)
    @customer = customer
    @customer_id = @customer.id
  end

  def generate_token
    Braintree::ClientToken.generate(customer_id: @customer_id)
  end   
end
4

1 回答 1

2

我在布伦特里工作。如果您对我们的 API 和客户端库有任何具体问题,您可以随时联系我们的支持团队

您的存根响应正文需要压缩。您可以像这样创建一个空的 gzip 压缩字符串:

irb(main):010:0> require 'stringio' 
=> false
irb(main):011:0> require 'zlib'
=> false
irb(main):012:0> Zlib::GzipWriter.new(StringIO.new("w")).close.string
=> "\u001F\x8B\b\0:\x87GU\0\u0003\u0003\0\0\0\0\0\0\0\0\0"

所以试试这个status_ok方法:

def status_ok
  {
    status: 200,
    body: "\u001F\x8B\b\0:\x87GU\0\u0003\u0003\0\0\0\0\0\0\0\0\0",
    headers: {"Content-Encoding" => "gzip"}
  } 
end
于 2015-05-04T14:49:33.963 回答