Skip to content
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

Test friction #1559

Open
sammyhenningsson opened this issue May 1, 2024 · 2 comments
Open

Test friction #1559

sammyhenningsson opened this issue May 1, 2024 · 2 comments

Comments

@sammyhenningsson
Copy link

sammyhenningsson commented May 1, 2024

Basic Info

  • Faraday Version: 2.9.0
  • Ruby Version: 3.3

Issue description

I find it painful to test code using Faraday. I'm wondering if it would be possible to improve the testing experience. Or please give me suggestions if I can improve my usage of Faraday.

Typically will write clients that uses Faraday internally. For example:

class FooClient
  attr_reader :base_url

  def initialize(base_url: nil)
    @base_url = base_url || "https://example.com"
  end

  def foobar(search:)
    get('foobar', {search:})
  end

  private

  def get(path, params = nil, headers = nil)
    connection.get(path, params, headers).body
  end

  def connection
    headers = {'Accept' => 'application/json'}
    @connection ||= Faraday.new(url: base_url, headers:) do |f|
      f.adapter Rails.application.config.x.faraday.adapter # :test or :net_http depending on environment
    end
  end
end

I don't understand how I should stub requests that such a client makes. From the documentation, its says that stubbing should be done when initializing a Faraday::Connection. But (at least the way I write my clients), I don't have control over these internals and I would like a more "global" way of stubbing requests.
Do you think there's any way this can be done/improved?
Or do you have any suggestion for improving the way I design my clients?

@iMacTia
Copy link
Member

iMacTia commented May 1, 2024

Hi @sammyhenningsson, this is actually a great question!
It would make for a really good discussion, but I think I might leave it as an issue to make it easier for people to find it.

From the documentation, its says that stubbing should be done when initializing a Faraday::Connection
I'd love to know which documentation you're referring to here. My guess is you're referring to the test adapter docs.
And you're right, the docs clearly state "This can be used to mock out network services in an application's unit tests".

However as you rightly pointed out, this isn't easy when you're developing a client, because that would require some sort of dependency injection, which would cause the test code to differ from the one used in production.

To be fair, I believe the test adapter is more suited to write tests for middleware, not for API clients like the one you're building. I also build lots of those and in my experience there are 2 main ways to write tests for these:

  1. Using Webmock (which supports Faraday out of the box); or
  2. Using VCR (which operates at a higher level)

Personally, I prefer the former for a variety of reasons, but I also know plenty of people who prefer the latter.
Regardless of your preference, these are both external dependencies that you can use to write tests and are quite good at that, to the point that I don't think we need to introduce built-in tools in Faraday itself to mimic their features.

I should probably update the docs to formalise this advice, but interested in your feedback before I do that 🙂

@sammyhenningsson
Copy link
Author

Thank you for this explanation!
I guess webmock might be the best solution. (Not too big of a fan of VCR). I didn't realize that the test adapter was meant to be for middleware. But now I understand the reasoning for it.
Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants