Reputation: 266910
What is the elixir way to mock 3rd party libraries.
So during registration I want to send out an email to the user. In development I want the email module to use a different mock module that would say just output a log trace instead of really sending out an email.
What options are there in elixir for this? Is this something I can do in the config in phoenix to swap implementations?
Upvotes: 1
Views: 153
Reputation: 5963
In my personal experience, sometimes it's nice to have a dev instance/workspace/etc that my dev environment hits. Often the only difference between hitting the dev instance and the prod instance is which credentials/URL the API is called with, which makes my prod/dev code exactly the same.
If, however, you would prefer to do dependency injection, you could use the config to point at a dependency. I've never used config this way in production, and it may be bad practice, but it's how I would approach the problem.
Here's an example around Enum.map/2
& Stream.map/2
. Let's say your dev config looks like this:
# config/dev.exs
config :sandbox, mapper: Enum
When you ask for :mapper
, you get the Enum
module and can call it like you would directly:
iex> Application.get_env(:sandbox, :mapper)
Enum
iex> Application.get_env(:sandbox, :mapper).map(0..2, &Integer.to_string/1)
["0", "1", "2"]
Let's say, however, your prod config looks like this:
# config/prod.exs
config :sandbox, mapper: Stream
When you get :mapper
in prod (using the same code as in dev), you get the Stream
module:
iex> Application.get_env(:sandbox, :mapper)
Stream
iex> Application.get_env(:sandbox, :mapper).map(0..2, &Integer.to_string/1)
#Stream<[enum: 0..2, funs: [#Function<48.15162342/1 in Stream.map/2>]]>
There's a trade-off doing dependency injection this way vs. passing it into every function call: granularity. You don't have to pass it in everywhere, but you are also stuck with whatever you set at compile time.
Upvotes: 0
Reputation: 120990
What is the elixir way to mock 3rd party libraries?
This excellent article by José Valim is a must read; I would quote it all if I could (the emphasis below is mine.)
I will emphasize this later on but I always consider “mock” to be a noun, never a verb.
and
when it comes to make the tests pass, a common practice is to just go ahead and mock (warning! mock as a verb!) the underlying [...]
Also, this article by Lasse Ebert is worth it to read.
Upvotes: 1