Mox Switch Context / Abstraction Layers

Hi all! Deleted the previous post, formatting was very messed up. Apologies!

I’ve got some Mox tests working with some API functions, but the current way I have it organized doesn’t seem quite right to me. Hoping for some guidance and to understand better.

Current module context-

api_calls.ex houses all of the direct interaction with urls and decoding the whole of JSON responses, i.e.

  defp handle_response(url, headers) do
    case http_client().get(url, headers) do
      {:ok, %{body: body}} ->
        Jason.decode!(body)

      {:error, reason} ->
        {:error, reason}
    end
  end

  defp http_client, do: Application.get_env(:my_app, :http_client)

fetch_users.ex are the individual functions that call the API/url functions and provide specific transformations of the returned JSON data, clean it up, maps etc. This is where I’m noting the behaviour for Mox to mock. A separate behaviour.ex file has the callbacks to all the functions here i.e.


@behaviour FetchUsersBehaviour

def get_ids(names, location) do
    names
    |> Enum.map(&Task.async(fn -> ApiCalls.fetch_id(&1, location) end))
    |> Enum.map(&Task.await(&1))
    |> Enum.map(& &1["ids"])
  end

fetch_users_switch.ex calls all the functions in fetch_users.ex, but with the impl layer that Mox uses. i.e.

 def get_ids(names, location) do
    fetch_impl().get_ids(names, location)
  end

defp fetch_impl() do
    Application.get_env(:my_app, :users, FetchUsers)
  end

fetcher.ex is the main module that chains/pipes together all the individual functions of fetch_users.ex, but does so by going through fetch_users_switch.ex.

alias FetchUsersSwitch, as: Fetch

def do_all(name, location) do
name
      |> Fetch.get_ids(location)
      |> Fetch.foo(location)
      |> Fetch.bar(location)
      |> Fetch.more(location)
end

My question might be more about subjectivity with how things should be organized, but am I doing this correctly with integrating Mox? Is there a simpler way to do this and Ive just overthought it?