Fl4m3Ph03n1x

Fl4m3Ph03n1x

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?

Showing Posts 1 to 5

idi527

idi527

Not sure if it applies, but I rarely have a need for mocks – I just try my hardest to keep everything pure. And when I do need to get dirty (usually at the edges of the system, like interaction with some external api), I only have to write a few (integration?) tests to exercise the “protocol”.

I started following this approach in elixir after first applying these ideas in swift:

But I mostly use message passing / plug’s conn-like (or ecto’s changeset) structs instead of reducers in elixir. The big downside of this approach when used with message passing is that messages in erlang are untyped, so i can never be really sure that the program works as expected (unlike in swift, rust, or pony (where messages are typed)).

Fl4m3Ph03n1x

Fl4m3Ph03n1x OP

As do I, but if your entire application is pure, then it is also entirely useless :stuck_out_tongue:

Side effects are the bane of all programmers, but they are also a necessary evil we must deal with. That’s why these types of discussions exist :smiley:

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.
Fl4m3Ph03n1x

Fl4m3Ph03n1x OP

I was actually afraid of this. I still have some trouble with Rainsberger’s vision. He mentions “test doubles”, not mocks or anything in specific. If I pass a stub ( instead of a mock ) to a function, am I still not adhering to his vision?

From the Java world where ( up until last year IIRC ) you couldn’t pass lambdas the only solution was to create Mocks. But in Elixir, JS and many other languages where functions are first class citizens, do we really need mocks at all?

Really wish I could talk about this with someone.
I think the thing I miss the most is a good example … but that is a topic for another post.

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:

— All posts loaded —

Where Next? Top

Trending in Discussions Top

AstonJ
As the title says, please share what you’ve been up to with Elixir. Whether that’s been learning it, looking into it, making stuff with i...
2977 92995 915
New
AstonJ
The obligatory hello world thread! Who are you and where are you from? :stuck_out_tongue:
4616 55835 594
New
caslu
I want to open this thread for you all to discuss and help those who really like Ash but are still hesitant to use it in a real project. ...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
Herve37
We’re evaluating API mocking tools for OpenAPI-based projects and would love to hear what other teams are using. We’re particularly inte...
New
GES233
I’m posting this in response to Jose’s recent tweet (Cr. link) : People are sleeping on Elixir for a coding harness: Hot-code swappi...
New
_mfierro
Hello, I wrote Stop My Hand, a Scattergories-like web application using Phoenix/LiveView as my learning project for Elixir (after readin...
New

Other Trending Topics Top

garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve. They are GUI (Emerge) and State management (S...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
wintermeyer
There are three potential reasons for members of this forum to have a look at https://vutuv.de You are tired or annoyed of LinkedIn. Yo...
New
webofbits
Aludel - LLM Evaluation Workbench Aludel is an embeddable Phoenix LiveView dashboard for evaluating and comparing LLM prompts across mult...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews