Setting up a Mock with behaviours

I’m creating some mocks in my application for testing purposes. I want to create a contract between these mocks and the real module using behaviours. I’d like to do this in the correct way.

For example, I have a GenServer which does some work called Vendor.Manager. I’d like to create a sandbox version called Vendor.Manger.Sandbox and I want to make sure it implements the same functions.

Can I create @callback functions in the Vendor.Manager along with the GenServer behaviour, or do I need to create a separate module for the callbacks? I’d prefer to set it up this way:

defmodule Vendor.Manager do

  @callback notify() :: :ok

  use GenServer
  
  def start_link, do: ...

  def notify, do: GenServer.cast(__MODULE__, :do_something)

  ## Callbacks
  def init(_opts), do: ...
  ...
end

and in my sandbox version:

defmodule Vendor.Manager.Sandbox do

  use Vendor.Manager

  def notify, do: :ok

end
1 Like

Just leaving here a popular link about Mocking in Elixir: http://blog.plataformatec.com.br/2015/10/mocks-and-explicit-contracts/

Ha, ya that’s how I got this far!

To close the loop on this: I ended up implementing it the way I proposed in my question except with @behaviour Vendor.Manager. It seems to be working fine.

defmodule Vendor.Manager.Sandbox do

  @behaviour Vendor.Manager

  def notify, do: :ok

end