Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Fix #to_rack to handle non-array response bodies. #150

Merged
merged 1 commit into from

2 participants

Tammer Saleh Bartosz Blimke
Tammer Saleh

When using #to_rack with a Rails endpoint, such as:

stub_request(:any, %r{api.example.com/.*}).to_rack(Rails.application)

...you receive the following error:

NoMethodError: undefined method `join' for #<ActionDispatch::Response:0x007ffd06e6f540>

Turns out ActionDispatch::Response is in the right. A Rack response body
is only required to implement #each, not #join.

This patch fixes #to_rack to build the body using the #each method.

Tammer Saleh Fix #to_rack to handle non-array response bodies.
When using #to_rack with a Rails endpoint, such as:

  stub_request(:any, %r{api.example.com/.*}).to_rack(Rails.application)

...you receive the following error:

  NoMethodError: undefined method `join' for #<ActionDispatch::Response:0x007ffd06e6f540>

Turns out ActionDispatch::Response is in the right. A Rack response body
is only required to implement #each, not #join.

This patch fixes #to_rack to build the body using the #each method.
146acef
Bartosz Blimke
Owner

Thank you for the patch!

Bartosz Blimke bblimke merged commit d0c58e9 into from
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jan 19, 2012
  1. Fix #to_rack to handle non-array response bodies.

    Tammer Saleh authored
    When using #to_rack with a Rails endpoint, such as:
    
      stub_request(:any, %r{api.example.com/.*}).to_rack(Rails.application)
    
    ...you receive the following error:
    
      NoMethodError: undefined method `join' for #<ActionDispatch::Response:0x007ffd06e6f540>
    
    Turns out ActionDispatch::Response is in the right. A Rack response body
    is only required to implement #each, not #join.
    
    This patch fixes #to_rack to build the body using the #each method.
This page is out of date. Refresh to see the latest.
8 lib/webmock/rack_response.rb
View
@@ -10,12 +10,18 @@ def evaluate(request)
status, headers, response = @app.call(env)
Response.new(
- :body => response.join,
+ :body => body_from_rack_response(response),
:headers => headers,
:status => status
)
end
+ def body_from_rack_response(response)
+ body = ""
+ response.each { |line| body << line }
+ return body
+ end
+
def build_rack_env(request)
uri = request.uri
headers = request.headers || {}
15 spec/support/my_rack_app.rb
View
@@ -1,6 +1,17 @@
require 'rack'
class MyRackApp
+ class NonArrayResponse
+ # The rack response body need not implement #join,
+ # but it must implement #each. It need not be an Array.
+ # ActionDispatch::Response, for example, exercises that fact.
+ # See: http://rack.rubyforge.org/doc/SPEC.html
+
+ def each(*args, &blk)
+ ["This is not in an array!"].each(*args, &blk)
+ end
+ end
+
def self.call(env)
case env.values_at('REQUEST_METHOD', 'PATH_INFO')
when ['GET', '/']
@@ -8,6 +19,8 @@ def self.call(env)
when ['GET', '/greet']
name = env['QUERY_STRING'][/name=([^&]*)/, 1] || "World"
[200, {}, ["Hello, #{name}"]]
+ when ['GET', '/non_array_response']
+ [200, {}, NonArrayResponse.new]
when ['POST', '/greet']
name = env["rack.input"].read[/name=([^&]*)/, 1] || "World"
[200, {}, ["Good to meet you, #{name}!"]]
@@ -15,4 +28,4 @@ def self.call(env)
[404, {}, ['']]
end
end
-end
+end
8 spec/unit/rack_response_spec.rb
View
@@ -13,6 +13,14 @@
response.body.should include('This is my root!')
end
+ it "should behave correctly when the rack response is not a simple array of strings" do
+ request = WebMock::RequestSignature.new(:get, 'www.example.com/non_array_response')
+ response = @rack_response.evaluate(request)
+
+ response.status.first.should == 200
+ response.body.should include('This is not in an array!')
+ end
+
it "should send along params" do
request = WebMock::RequestSignature.new(:get, 'www.example.com/greet?name=Johnny')
Something went wrong with that request. Please try again.