I was wondering if there is an easy automated way to do this. We have a test suite that we run and we mock out external API calls for obvious reasons. But sometimes something does not get mocked like it should. It would be wonderful if there was a way to automatically catch that across our test suite.
Is there a solution for this? My google-fu failed me
One way to do it is to add a behaviour for the HTTP calls (get, post, delete, etc) and then use the Mox implementation to handle all HTTP responses in the test environment:
defomodule MyApp.HttpClient do
def get(url, headers, options) do
impl().get(url, headers, options)
end
defp impl do
Application.get_env(:my_app, :http_client_impl, MyApp.HttpClient.DefaultImpl)
end
end
As an extra layer of fault-tolerance, perhaps you could check in the actual client itself to make sure nobody calls it manually in the wrong environment:
defmodule MyApp.HttpClient.DefaultImpl do
def get(url, headers, options) do
if Application.fetch_env!(:my_app, :http_client_impl) != __MODULE__,
do: raise("application is not configured to use this client")
# ...
end
end
While I do often reach for Mox for testing. What I’m looking for here is a way to detect HTTP calls without having to inject a behavior because I’m looking to catch HTTP calls that are inserted by accident, including any calls added in libraries.
I see, that’s an interesting use case. I can only think of 3 solutions then:
Does the library support overriding the base URL or domain used on the HTTP calls? Then you can change it to localhost and use the Bypass library to mock the responses.
Otherwise, you would need to open a PR on the library repository (or clone it) to allow overriding the HTTP client (by adding a behaviour) or base URL (solution 1).
Add a behaviour/wrapper and call it instead of the library