yeroc
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?
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #javascript
- #code-sync
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance








