lostisland / faraday

Simple, but flexible HTTP client library, with support for multiple backends.
https://lostisland.github.io/faraday
MIT License
5.76k stars 978 forks source link

Relative paths for `test` adapter (stubs) #1146

Closed AlexWayfer closed 4 years ago

AlexWayfer commented 4 years ago

Basic Info

Issue description

I have such connection:

Faraday.new(
  url: "https://api.twitch.tv/kraken"
)

And such code with this connection:

connection.get "users/#{user_id}"

And I want to test it. But with regular adapter connection accepts relative paths (see above), and with :test adapter it does not:

Faraday::Adapter::Test::Stubs.new do |stub|
  stub.get("users/#{user_id}") { [200, {}, stubbed_user] }
end
Twitch::Client
  #user
    with argument
      example at ./spec/twitch/client_spec.rb:146 (FAILED - 1)
      #body
        example at ./spec/twitch/client_spec.rb:204 (FAILED - 2)

Failures:

  1) Twitch::Client#user with argument 
     Failure/Error: connection.get "users/#{user_id}"

     Faraday::Adapter::Test::Stubs::NotFound:
       no stubbed request for get /kraken/users/44322889 
     Shared Example Group: "success" called from ./spec/twitch/client_spec.rb:199
     # ./lib/twitch/client.rb:49:in `user'
     # ./spec/twitch/client_spec.rb:174:in `block (3 levels) in <top (required)>'
     # ./spec/twitch/client_spec.rb:144:in `block (3 levels) in <top (required)>'
     # ./spec/twitch/client_spec.rb:146:in `block (3 levels) in <top (required)>'

  2) Twitch::Client#user with argument #body 
     Failure/Error: connection.get "users/#{user_id}"

     Faraday::Adapter::Test::Stubs::NotFound:
       no stubbed request for get /kraken/users/44322889 
     # ./lib/twitch/client.rb:49:in `user'
     # ./spec/twitch/client_spec.rb:174:in `block (3 levels) in <top (required)>'
     # ./spec/twitch/client_spec.rb:202:in `block (5 levels) in <top (required)>'
     # ./spec/twitch/client_spec.rb:204:in `block (5 levels) in <top (required)>'

Finished in 0.00367 seconds (files took 0.34086 seconds to load)
2 examples, 2 failures

If I add /kraken to stub — it works.

Steps to reproduce

See code above.

AlexWayfer commented 4 years ago

Blocked by #1147.

AlexWayfer commented 4 years ago

I don't know how to implement this.

Specifically, I don't know how can I access Connection object from Adapter object.

I'm about to close this issue and write a code like:

MY_CONNECTION = Faraday.new(
  url: "https://api.twitch.tv/kraken"
)

stub.get("#{MY_CONNECTION.url_prefix}users/#{user_id}") { [200, {}, stubbed_user] }

(although it's not beautiful)

iMacTia commented 4 years ago

@AlexWayfer the adapter should definitely NOT be able to access the connection, it doesn't make sense from a design point of view.

I still don't understand why you have this issue, as the requests are stubbed anyway, you could just create the faraday connection without a prefix, or add the prefix the all the stubs.

If that's not viable (but I'd be curious to know why), then the TestAdapter also support regexp as of #552, so that would be another viable solution.

AlexWayfer commented 4 years ago

I still don't understand why you have this issue, as the requests are stubbed anyway, you could just create the faraday connection without a prefix, or add the prefix the all the stubs.

If that's not viable (but I'd be curious to know why)

DRY. The reason is "Don't Repeat Yourself". I can re-use base path any number of times, but I don't want to.

My PR doesn't break anything except something like Responsibility abstraction.

iMacTia commented 4 years ago

Then before we break anything, can you let me know if the regex solution works for you and keeps your tests DRY?

AlexWayfer commented 4 years ago

I'm going to close this issue and related PR. Sorry, but I want to use cassettes (VCR) for now. And I guess I can use regexp or something else. With time I've got the point of requests stubs, I guess. For example, if I change API base URI (API version) — tests should fails.

Thank you.

iMacTia commented 4 years ago

Completely agree, cassettes are also my personal favourite testing system, much more flexible and powerful than the test adapter.