diff --git a/README.md b/README.md index d424f3ad..38d6d609 100644 --- a/README.md +++ b/README.md @@ -330,6 +330,16 @@ stub_request(:any, "www.example.com"). Net::HTTP.get('www.example.com', '/') # ===> "abc\n" ``` +### Response with JSON body + +```ruby + +stub_request(:any, "www.example.com"). + to_return_json(body: {foo: "bar"}) + +Net::HTTP.get('www.example.com', '/') # ===> "{\"foo\": \"bar\"}" +``` + ### Response with custom status message ```ruby diff --git a/lib/webmock/request_stub.rb b/lib/webmock/request_stub.rb index 8c831c5c..85d971a2 100644 --- a/lib/webmock/request_stub.rb +++ b/lib/webmock/request_stub.rb @@ -29,9 +29,13 @@ def to_return_json(*response_hashes) json_response_hashes = [*response_hashes].flatten.map do |resp_h| headers, body = resp_h.values_at(:headers, :body) + + body = body.call if body.respond_to?(:call) + body = body.to_json unless body.is_a?(String) + resp_h.merge( headers: {content_type: 'application/json'}.merge(headers.to_h), - body: body.is_a?(Hash) ? body.to_json : body + body: body ) end diff --git a/spec/unit/request_stub_spec.rb b/spec/unit/request_stub_spec.rb index e7a8acfd..c8e3324d 100644 --- a/spec/unit/request_stub_spec.rb +++ b/spec/unit/request_stub_spec.rb @@ -69,6 +69,32 @@ expect(@request_stub.response.status).to eq([500, ""]) end + it "should json-ify an Array body" do + @request_stub.to_return_json(body: [{abc: "def" }]) + expect(@request_stub.response.body).to eq('[{"abc":"def"}]') + end + + it "should json-ify any object responding to `to_json`" do + record = double("SomeRecord") + allow(record).to receive_messages(to_json: '{"what":"something"}.') + + @request_stub.to_return_json(body: record) + expect(@request_stub.response.body).to eq('{"what":"something"}.') + end + + it "should not over-json-ify a String body" do + @request_stub.to_return_json(body: '{"abc":"def"}') + expect(@request_stub.response.body).to eq('{"abc":"def"}') + end + + it "should json-ify any callable proc or lambda to body" do + record = double("SomeRecord") + allow(record).to receive_messages(to_json: '{"what":"something callable"}.') + + @request_stub.to_return_json(body: -> { record }) + expect(@request_stub.response.body).to eq('{"what":"something callable"}.') + end + it "should apply the content_type header" do @request_stub.to_return_json(body: {abc: "def"}, status: 500) expect(@request_stub.response.headers).to eq({"Content-Type"=>"application/json"})