When a module relies on external HTTP requests, your tests should not. The Req.Test module provides a clean way to stub responses and keep your tests fast and predictable. This post shows how to configure your application for testing, integrate Req.Test into your HTTP client, and write focused tests with controlled behaviour.
Test-specific configuration
To activate Req.Test only in the test environment, override your Req options in config/test.exs:
# config/test.exs
config :my_app,
http_client_options: [
plug: {Req.Test, MyApp.HTTPClient}
]
This ensures that all requests going through your client module will be intercepted by Req.Test during tests.
Building a Req client that merges configuration
Your client module stays environment-agnostic. It defines its base options and merges in whatever is configured for tests:
defmodule MyApp.HTTPClient do
@default_timeout 5_000
@max_retries 3
def new(url, headers \\ []) do
[
url: url,
redirect: true,
compressed: true,
headers: headers
]
|> Keyword.merge(Application.get_env(:my_app, :http_client_options, []))
|> Req.new()
end
end
In non-test environments, the merge adds nothing and the client performs real requests. In tests, the plug activates the Req.Test pipeline.
Writing tests with stubbed responses
Req.Test.stub/2 lets you define responses for each request made via the client:
test "handles 304 responses" do
Req.Test.stub(MyApp.HTTPClient, fn conn ->
conn
|> resp(304, "body")
end)
response = MyApp.HTTPClient.new("https://example.com/")
|> Req.request()
assert response.status == 304
end
Each test run receives the same deterministic response, keeping your test suite stable and independent of the network.
Conclusion
Req.Test is a straightforward and powerful tool for isolating your tests from external HTTP dependencies. By pushing configuration into your test environment and keeping your client code clean, you gain reproducible tests without sacrificing clarity or maintainability.
If this post was enjoyable or useful for you, please share it! If you have comments, questions, or feedback, you can email my personal email. To get new posts, subscribe use the RSS feed.