pepicrft
Application_module - Better mocking ergonomics
Hey folks ![]()
I just shipped a new Elixir package to improve the ergonomics using mocking libraries like Mox or Hammox, application_module. I talked about the motivations in detail in this blog post, but I’ll leave you here with the TL;DR;
- Mox and Hammox propose to have a runtime function that reads the module from the application environment.
- This is common across all the modules whose tests will want to mocks some of their dependencies. This leads to a lot of duplications and potentially inconsistencies in how that information is structured inside the application environment.
- There might also be inconsistencies arising from how developers organize the behaviours and their default implementations.
I decided to eliminate all the duplications and embrace a more conventional approach enforced via macros. Here’s an example that illustrates the before and after using the package:
Before
defmodule MyModule do
@behaviour __MODULE__.Behaviour
def hello(name) do
application_env_module().hello(name)
end
def application_env_module() do
get_in(Application.get_env(:my_app, :modules), [:my_module]) || __MODULE__.Implementation
end
defmodule Implementation do
@behaviour MyModule.Behaviour
def hello(name) do
"Hello #{name}"
end
end
defmodule Behaviour do
@callback hello(name :: String.t()) :: any()
end
end
After
defmodule MyModule do
use Application.Module
defimplementation do
def hello(name) do
"Hello #{name}"
end
end
defbehaviour do
@callback hello(name :: String.t()) :: any()
end
end
Any feedback is truly appreciated. It was my first time implementing macros myself so I went through a bunch of hiccups and back-and-forths.
Popular in Libraries
Hey everyone :wave:
Excited to join this forum - I am one of the founders and current project maintainers of a popular and open-source U...
New
Been making an MLElixir thing (not released yet…) for fun in spare time in the past day. I’m just trying to see how much I can get an ML...
New
EDIT: since Ecto 3.0 final version is out, this post was amended to use the final versions in the instructions below.
Hi everyone,
We a...
New
What is ContEx?
A pure Elixir server-side data plotting/charting library outputting SVG.
It has nice barcharts in particular and works g...
New
I’ve published the first version of my Makeup library. It’s a syntax highlighter for Elixir in the spirit of Pygments, Currently it highl...
New
Flop is an Elixir library that applies filtering, ordering and pagination parameters to your Ecto queries.
offset-based pagination with...
New
PhoenixWS - Websockets over Phoenix Channels
Source code on Github here: https://github.com/tmbb/phoenix_ws
Phoenix channels are a great...
New
Hi everyone!
I’m thrilled to announce a huge thing. We have been developing Elixir Moon Design System for quite a while. We are finally ...
New
Bandit is an HTTP server for Plug and WebSock apps.
Bandit is written entirely in Elixir and is built atop Thousand Island. It can serve...
New
Expat is a tiny experiment I did for extracting patterns and being able to reuse them (compose and share patterns between elixir librarie...
New
Other popular topics
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1]
15:22:35.803 [error] gen_event {lager_file_backend...
New
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
New
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this:
...
New
I have an umbrella app.
Some of the apps inside depend on other apps in the umbrella, unsurprisingly.
I'm writing a test for one of t...
New
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
Hi guys, i’m new in the Elixir world, and i have to say, that i love it!
i’m having some problem to understand anonymous functions with ...
New
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: )
Hello all, this is ...
New
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New







