-
Notifications
You must be signed in to change notification settings - Fork 980
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Stubbing API Request #232
Comments
This would be easier on the new CallbackBuilder. Instead of a single array of every middleware, it stores them in 2 arrays around the adapter. You'll be able to set the adapter much easier now without having to introspect the stack or anything like that. What about something like: @conn.stub do |stubs|
stubs.get...
end Though, I guess if you're writing proper tests, you'll only need to stub one thing :) def setup
@conn.stubs.clear
end
def test_foo
@conn.stubs.get('/foo') { [200, {}, ''] }
assert_equal 200, @conn.get('/foo').status
end This could go in a |
That's how I'm handling it now, along with a helper to pick up the connection defaults for the stubs. require 'faraday'
class Client
extend Forwardable
def_delegator :@connection, :get
def initialize(api_url, api_key)
@connection = Faraday.new(
url: api_url,
params: { api_key: api_key },
headers: { accept: 'application/json' }
) do |conn|
# request/response middleware... retry, json parsing, etc.
if respond_to?(:stubs)
conn.adapter :test, stubs
else
conn.adapter Faraday.default_adapter
end
end
end
end
require 'faraday/adapter/test'
module ClientHelpers
def stubs
@stubs ||= Faraday::Adapter::Test::Stubs.new
end
# Add api_url base path and default request params/headers to stub
def stub(path, params = {}, headers = {}, &block)
path = File.join(@connection.url_prefix.path, path) + '?' +
Faraday::Utils.build_nested_query(params.merge(@connection.params))
headers = @connection.headers.merge(headers)
resp = Response.new(200, {}, '')
block.call(resp)
stubs.get(path, headers) { [resp.status, resp.headers, resp.body] }
end
class Response < Struct.new(:status, :headers, :body)
def headers
if body.start_with?('{')
self[:headers].merge('Content-Type' => 'application/json;charset=utf-8')
else
self[:headers].merge('Content-Type' => 'text/html;charset=utf-8')
end
end
end
end
Client.send(:include, ClientHelpers)
require 'minitest/autorun'
class ClientTest < MiniTest::Unit::TestCase
def setup
@client = Client.new('http://domain.com/api_root/', 'my_key')
end
def test_client
@client.stub(
'search', { query: 'ping' }, { 'User-Agent' => 'minitest' }
) {|res| res.body = 'pong' }
res = @client.get do |req|
req.url 'search'
req.params['query'] = 'ping'
req.headers['User-Agent'] = 'minitest'
end
assert_equal 200, res.status
assert_equal({ 'Content-Type' => 'text/html;charset=utf-8' }, res.headers)
assert_equal 'pong', res.body
assert_equal(
{ 'Accept' => 'application/json', 'User-Agent' => 'minitest' },
res.env.request_headers
)
assert_equal(
{ 'api_key' => 'my_key', 'query' => 'ping' },
res.env.params
)
assert_equal 'http://domain.com/api_root/search?api_key=my_key&query=ping',
res.env.url.to_s
end
end Well, maybe not exactly like this, but you get the idea :) Feel free to close this if you like, as this really isn't an issue. |
Not a fan of Here is a clean way to replace a real adapter with test one and make request stubs in the same go: # for Faraday 0.8.x
def stub_request(conn, adapter_class = Faraday::Adapter::Test, &stubs_block)
adapter_handler = conn.builder.handlers.find {|h| h.klass < Faraday::Adapter }
conn.builder.swap(adapter_handler, adapter_class, &stubs_block)
end
# usage in tests:
stub_request(conn) do |stub|
stub.get '/nigiri/sake.json' do
[200, {}, 'hi world']
end
end |
Closing as alternative solution provided above |
Hey Rick,
Instead of having to create and pass in stubs, it would be nice if this was done automatically if none are given. For one, since autoload isn't being used, you have to require the Test adapter to do so. And in either case, having access to the stubs through the Connection would be nice too.
i.e. Instead of
You could just use
The following changes probably better illustrate my point:
https://github.com/burns/faraday/compare/stubbing
I'm not sure this is the correct answer. But since RackBuilder::Handler doesn't instantiate the adapter until the request, I don't see any other option. In fact, the Test adapter creates an instance of Stubs if none are passed in, but I see no way this could be used.
I believe you mentioned you were planning on some changes to RackBuilder and/or the stubbing API, so you may have other ideas. But, thought I'd throw this out there.
The text was updated successfully, but these errors were encountered: