Req - A batteries-included HTTP client for Elixir

Req.Test.stub/1,2 can be used to stub anything so you could stub Req options:

defmodule MyApp.MyClient do
  def new(options) do
    Req.new(...)
    |> merge_test_options()
  end

  if Mix.env() == :test do
    defp merge_test_options(req) do
      Req.merge(req, plug: Req.Test.stub(__MODULE__))
    end
  else
    defp merge_test_options(req) do
      req
    end
  end
end

# test with stub:
Req.Test.stub(MyApp.MyClient, fn conn -> ... end)

# integration test:
Req.Test.stub(MyApp.MyClient, nil)

When you set plug: nil it is as if you never set the option in the first place.

It’s a little bit ugly to change production code to accomodate tests like but I believe it is the most straighforward option. There could be more indirect ways I did not consider yet.