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
- Am I taking the correct conclusions, as in, do interfaces really allow us to skip the DMZ?
- How do you guys model your apps? Which patterns do you follow?