Hammox (Hammox v0.3.1) View Source
Hammox is a library for rigorous unit testing using mocks, explicit behaviours and contract tests.
See the README page for usage guide and examples.
Most of the functions in this module come from
Mox for backwards compatibility. As of
v0.1.0, the only Hammox-specific functions are protect/2
and protect/3
.
Link to this section Summary
Functions
See protect/3
.
Decorates functions with Hammox checks based on given behaviour.
See Mox.verify!/0.
Link to this section Types
Specs
Link to this section Functions
See Mox.allow/3.
See Mox.defmock/2.
See Mox.expect/4.
Specs
protect(module :: module()) :: %{required(atom()) => (... -> any())}
protect(mfa :: mfa()) :: (... -> any())
See protect/3
.
Specs
protect(module :: module(), funs :: [function_arity_pair()]) :: %{ required(atom()) => (... -> any()) }
protect(mfa :: mfa(), behaviour_name :: module()) :: (... -> any())
protect(implementation_name :: module(), behaviour_name :: module()) :: %{ required(atom()) => (... -> any()) }
See protect/3
.
Specs
protect( module :: module(), behaviour_name :: module(), funs :: [function_arity_pair()] ) :: %{required(atom()) => (... -> any())}
Decorates functions with Hammox checks based on given behaviour.
Basic usage
When passed an MFA tuple representing the function you'd like to protect,
and a behaviour containing a callback for the function, it returns a new
anonymous function that raises Hammox.TypeMatchError
when called
incorrectly or when it returns an incorrect value.
Example:
defmodule Calculator do
@callback add(integer(), integer()) :: integer()
end
defmodule TestCalculator do
def add(a, b), do: a + b
end
add_2 = Hammox.protect({TestCalculator, :add, 2}, Calculator)
add_2.(1.5, 2.5) # throws Hammox.TypeMatchError
Batch usage
You can decorate all functions defined by a given behaviour by passing an implementation module and a behaviour module. Optionally, you can pass an explicit list of functions as the third argument.
The returned map is useful as the return value for a test setup callback to set test context for all tests to use.
Example:
defmodule Calculator do
@callback add(integer(), integer()) :: integer()
@callback add(integer(), integer(), integer()) :: integer()
@callback add(integer(), integer(), integer(), integer()) :: integer()
@callback multiply(integer(), integer()) :: integer()
end
defmodule TestCalculator do
def add(a, b), do: a + b
def add(a, b, c), do: a + b + c
def add(a, b, c, d), do: a + b + c + d
def multiply(a, b), do: a * b
end
%{
add_2: add_2,
add_3: add_3,
add_4: add_4
multiply_2: multiply_2
} = Hammox.protect(TestCalculator, Calculator)
# optionally
%{
add_2: add_2,
add_3: add_3,
multiply_2: multiply_2
} = Hammox.protect(TestCalculator, Calculator, add: [2, 3], multiply: 2)
Behaviour-implementation shortcuts
Often, there exists one "default" implementation for a behaviour. A common practice is then to define both the callbacks and the implementations in one module. For these behaviour-implementation modules, Hammox provides shortucts that only require one module.
Example:
defmodule Calculator do
@callback add(integer(), integer()) :: integer()
def add(a, b), do: a + b
end
Hammox.protect({Calculator, :add, 2})
# is equivalent to
Hammox.protect({Calculator, :add, 2}, Calculator)
Hammox.protect(Calculator, add: 2)
# is equivalent to
Hammox.protect(Calculator, Calculator, add: 2)
Hammox.protect(Calculator)
# is equivalent to
Hammox.protect(Calculator, Calculator)
See Mox.set_mox_global/1.
See Mox.stub/3.
See Mox.stub_with/2.
See Mox.verify!/0.
See Mox.verify!/1.