simpler v0.2.1 Simpler.Mock

A generic Mock module which can receive expectations and later verify them. Verification is optional. This module is a work in progress driven by real-world testing needs, rather than by grand ideas. As such, it is fairly minimal.

Mocks are supported in the code using it by making indirect calls through references. So the production code holds a reference as a {mod, pid} tuple and calls code like:

mod.do_something(pid, arg1, ...)

By making the module variable in the production code, it becomes clean and simple to swap references between “real” and “mock” code on a case-by-case basis. In fact, it is simple enough to e.g. write a mock GenServer and use that in a test - this code is mostly syntactic sugar on top of it.

A quick example of how to create a mock:

use Simpler.Mock
{:ok, mock_dependency} = Mock.with_expectations do
  expect_call some_call(_some_pid, "you", "me"), reply: :ok_by_me, times: :any
end

This creates a mock that expects some_call zero to any times, will always reply :ok_by_me, and should have the arguments "you" and "me". The _some_pid argument starts with an underscore, which means it is ignored.

:reply and :times are both optional. The default reply is :ok and the default times is one. Mocks can have zero or more expectations - whenever an expectation is matched, it’s checked off the list, so when at the end of a run a call to

Mock.verify(mock)

is made, the call will succeed if all expectations have been seen.

Internall, a mock is a GenServer in an on-the-fly-defined, randomly-named module.

Summary

Functions

Verify expectations. This will flunk the test if the expectations didn’t match actual invocations

Generate a mock with expectations. Expectations are statements in the form

Functions

verify(pid)

Verify expectations. This will flunk the test if the expectations didn’t match actual invocations.

with_expectations(opts) (macro)

Generate a mock with expectations. Expectations are statements in the form

expect_call function_name(arg1, arg2, ...argN), reply: reply, times: times

Where reply and times are optional. Arguments can either be bound values or underscored placeholders - matching expectations with actual invocations will only take bound values into consideration, so underscored placeholders are effectively wildcards.

Returns {:ok, {mock_module, mock_pid}}