Blankman
Blankman

Reputation: 266910

Mocking 3rd party libraries in development

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

Answers (2)

Brett Beatty
Brett Beatty

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

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 120990

What is the elixir way to mock 3rd party libraries?

     

The answer is: dependency injection.


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

Related Questions