Mockable

Build StatusVersionHex DocsDownloadLicenseLast Updated

Zero boilerplate mock delegation.

Example

use Mockable in a module:

defmodule TemperatureClient do
  use Mockable

  @callback get_temperature(String.t()) :: integer()

  @impl true
  def get_temperature(city) do
    Req.get!("https://weather.com/temperatue/#{city}").body["temperature"]
  end
end

Configure the test environment (config/test.exs) to delegate function calls to the mock:

config :mockable, [
  {TemperatureClient, TemperatureClientMock}
]

Optionally configure the dev (config/dev.exs) environment to delegate function calls to a stub:

config :mockable, [
  {TemperatureClient, TemperatureClientStub},
  log: false
]

The log option shown above controls whether a log is emmitted for each invocation indicating the implementation used. This is compiled out in prod builds.

DO NOT config :mockable, ... in prod builds. Not being configured is what sets it to compile out.

Implement a dev stub like this:

defmodule TemperatureClientStub do
  @behaviour TemperatureClient

  @impl true
  def get_temperature(city) do
    30
  end
end

See docs for more information and examples.

Details

Mockable works by using a __before_compile__ macro to wrap each callback implementation in delegation logic. But it only does this if :mockable is configured, thus it does not affect production code.

Features/Benefits: