Fl4m3Ph03n1x

Fl4m3Ph03n1x

Mocking/Dependency injection in Elixir and Hexagonal Architecture

Background

So, this is the aftermath of reading Mocks and Explicit Contracts and Inversion of Control Containers and the Dependency Injection pattern from Martin Fowler.

Basically, I am trying to cement some ideas and I am looking for a discussion on the topic.

Mocks, are they evil?

Some people say Mocks are a code smell. Now, I stand with J. B. Rainsberger in that Mocks are not evil, they are the canary in the coal mine that is telling you something is about to explode. If you read the full article of Eric Elliot, you will also see he arrives to a somewhat similar conclusion.

Jose Valim seems to agree, and his solution to this issue is to make contracts (interfaces) explicit and never use mock as a verb ( use it as a noun ).

The interface approach to mocks

Now, I will agree that if you have a dependency on the outside horrible world, you should have instead an interface that protects your app and make your app depend on it.

The thing I am not so fond of is on how people seem to use mocks in Elixir. They just have their code call on a contract that has a real mock created and implemented somewhere else, usually a fake object or server with data.

I don’t like this

Call me lazy but I don’t like to create things. I have an aversion to creating false objects. It gives me work and I have to maintain them afterwards.

I much prefer passing the functions that interact to the outside horrible world to my happy zone. Not only that, I usually use the Constructor Injection Form of the Dependency Injection pattern as described by Martin Fowler.

So, if I have a module that needs to interact with the Outside Horrible world, I just pass the functions I need when I am starting it ( or in any other language, instantiating it ).

Valim does seem to agree with this, he mentions that passing functions (Mocks as local) is much easier than having to depend on Full Objects with Interfaces and that depend on the Application ENV. I agree with him.

What’s the issue?

The troubling thing here is that if I pass the test doubles directly via Constructor Injection then I am not applying the Hexagonal Architecture. In J. B. Rainsberger words, I am skipping the DMZ.

Questions

  1. Am I taking the correct conclusions, as in, do interfaces really allow us to skip the DMZ?
  2. How do you guys model your apps? Which patterns do you follow?

Most Liked

peerreynders

peerreynders

Am I taking the correct conclusions, as in, do interfaces really allow us to skip the DMZ?

I’m not sure I’m understanding what you are trying to imply. For the moment lets stay in Rainsberger’s Java world. My interpretation is

  • Happy Zone (HZ) gets to specify the interface that it needs to interact with the Horrible Outside World (HOW)
  • DMZ has to adhere to the HZ interface but is responsible for the implementation and ultimately interaction with the HOW. All interactions with the HOW are restricted to the DMZ.
  • Therefore any functions (e.g. your passed constructors) that directly interact with the HOW or are used by the HOW are to be quarantined inside the DMZ and are off limits for the HZ. Everything living in the DMZ will ultimately require an equivalent mock for the purpose for testing.
  • Those mocks are those false objects you don’t like creating - therefore you are not in alignment with Rainsberger’s vision.
peerreynders

peerreynders

If I pass a stub ( instead of a mock ) to a function, am I still not adhering to his vision?

Ok, I need to watch my terminology - what I should have said:

Those doubles are those false objects you don’t like creating.

Gerard Meszaros actually breaks test doubles down in xUnit Test Patterns: Refactoring Test Code (p.133):

So there is nothing wrong with using any sort of “test double”, including a stub.

From the Java world where ( up until last year IIRC ) you couldn’t pass lambdas the only solution was to create Mocks.

You have been able to use anonymous classes (a misnomer really, as it’s essentially a classless object) for a long time as ad hoc implementations of interfaces - which is really what you needed as you had to satisfy the entire interface for the sake of static typing.

do we really need mocks at all?

No. You mentioned Detroit-school vs. London-school - Martin Fowler actually uses the terms Classical vs. Mockist Testing. Classical testing existed before mocks emerged and made due with dummies, stubs, and fakes.

But the issue seems to be that you have been operating in the mockist tradition and acquired a distaste for expending effort on implementing dummies, stubs, and fakes.

With regards to the mockist approach even Martin Fowler comments:

Where Next?

Popular in Discussions Top

jeramyRR
This is an interesting article to read. Elixir’s performance, like usual, is excellent. However, it seems like the high CPU usage is co...
New
New
axelson
Decided against including more info in the title, but the gist is that Plataformatec sponsored projects will continue with the assets bei...
New
arcanemachine
https://nitter.net/josevalim/status/1744395345872683471 https://twitter.com/josevalim/status/1744395345872683471
New
Ankhers
Just a little information upfront. Generally speaking, if I feel like I need to either break a pipe chain or use an anonymous function in...
New
fireproofsocks
I’ve been working on an Elixir project that has required a lot of scripting. I usually reach for Elixir because I like it more (and in th...
New
boundedvariable
I am going through the kafka architecture. All the features what the kafka is providing are already in Erlang. I would like hear your opi...
New
acrolink
How does the two languages compare when it comes to server side application development? Any experiences or ideas? Thank you.
New
scouten
I’m looking for a host for the server part of a small (personal) side project that I’m working on. It’s currently written in Node.js and ...
New
sergio
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
New

Other popular topics Top

mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1144 53690 245
New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New
vegabook
I’m brand new to Phoenix and I have stripped one of the demo applications to the bone. I just want to get an svg up on the screen. Here i...
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 52341 488
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
svb
Hi! Currently I want to submit a form by pressing the Enter key. However, since my input field is of type “textarea” this is just adds a...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New

We're in Beta

About us Mission Statement