Background
Recently I have thrown again into the see of testing my functional code with Elixir. However I am finding it rather difficult to create tests for basic manager / collaborators communication because I find Elixir’s toolset lacking when it comes to spies and stubs. Pure functions only whose dependencies get injected, no mocks here, no modules.
Objective
Several approaches have been suggested to me when testing stubs and spies. The objective of this discussion is to have a (somewhat) comprehensive lists of strategies used with their pros and cons.
You may not 100% agree with the definitions I am about to suggest, but for the technical purposes of this discussion let’s simply go with them (you may disagree with me in another discussion )
Spies
A spy’s main objective is to tell how information about a function, such as:
- Was a function invoked?
- How many times it was invoked
- With what parameters it was invoked
Stubs
A stub’s main purpose is to direct the workflow of your program. This basically boils down to:
- returning an output you define at test level
You may force a function to raise an error or return a given value.
Common approaches
Following I discuss some common approaches to testing.
test process sends messages to self()
pros
- check a given function was called
- check with which arguments it was called
- does not use global state
cons
- cannot tell you a function was invoked precisely X times
- cannot change return value based on how many times a function was invoked
usage of :counters
(requires erlang 21.2)
pros
- allows you to know exactly how many times a given function was invoked
- allows you to, based on the number of times a function was called, return different results
- does not use global state
cons
- doesn’t allow you to know with which parameters a function was called with
More?
There are more solutions out there. @peerreynders suggested the use of named ETS tables to store state in tests and @hauleth the use of Agents. I look forward to having them join this conversation (if they want to ofc).
What other strategies do you know?