View Source Mockery (mockery v2.3.3)

Core functionality

Summary

Types

Used to avoid unnecessary compile-time dependencies between modules

Mockery uses tuple calls to send additional data to internal proxy module

Functions

Function used to create mock in context of single test process.

Function used to prepare module for mocking.

Types

Link to this type

elixir_module_as_string()

View Source
@type elixir_module_as_string() :: String.t()

Used to avoid unnecessary compile-time dependencies between modules

Examples

defmodule Foo do
  # this creates compile-time dependency between Foo and Bar
  @bar1 Mockery.of(Bar)

  # same result but without compile-time dependency
  @bar2 Mockery.of("Bar")
end

mix xref graph can be used to check difference between module and string versions

@opaque proxy_tuple()

Mockery uses tuple calls to send additional data to internal proxy module

Functions

Link to this function

mock(mod, fun, value \\ :mocked)

View Source

Function used to create mock in context of single test process.

Mock created in test won't leak to another process (other test, spawned Task, GenServer...). It can be used safely in asynchronous tests.

Mocks can be created with static value:

mock Mod, [fun: 2], "mocked value"

or function:

mock Mod, [fun: 2], fn(_, arg2) -> arg2 end

Keep in mind that function inside mock must have same arity as original one.

This:

mock Mod, [fun: 2], &to_string/1

will raise an error.

It is also possible to mock function with given name and any arity

mock Mod, :fun, "mocked value"

but this version doesn't support function as value.

Also, multiple mocks for same module are chainable

Mod
|> mock(:fun1, "value")
|> mock([fun2: 1], &string/1)
This function is deprecated. Mockery was not designed as solution for other libraries. It was a bad decision to try to workaround this. This approach was also extremely ugly and lacking all the advantages of Mockery .
@spec of(
  mod :: module() | elixir_module_as_string(),
  opts :: [{:by, module() | elixir_module_as_string()}]
) :: module() | proxy_tuple()

Function used to prepare module for mocking.

For Mix.env other than :test it returns module given in the first argument. If Mix.env equal :test it creates a proxy to the original module. When Mix is missing it assumes that env is :prod

Examples

Prepare for mocking (elixir module)

defmodule Foo do
  @bar Mockery.of("Bar")

  def foo do
    @bar.bar()
  end
end

It is also possible to pass the module in elixir format

@bar Mockery.of(Bar)

but it is not recommended as it creates an unnecessary compile-time dependency (see mix xref graph output for both versions).

Prepare for mocking (erlang module)

defmodule Foo do
  @crypto Mockery.of(:crypto)

  def foo do
    @crypto.rand_seed()
  end
end

Prepare for mocking with global mock

# test/support/global_mocks/bar.ex
defmodule BarGlobalMock do
  def bar, do: :mocked
end

# lib/foo.ex
defmodule Foo do
  @bar Mockery.of(Bar, by: BarGlobalMock)

  def foo do
    @bar.bar()
  end
end

OTP21+

Internally mockery is using tuple calls to pass additional data to its proxy module when mock is called. Tuple calls are disabled by default in OTP21+ and require additional compile flag to be reenabled.

defmodule Foo do
  @compile :tuple_calls
  @bar Mockery.of("Bar")

  # ...
end

If you don't want to reenable tuple calls, there's also new macro-based alternative (for more information see Mockery.Macro module).