View Source meck (meck v1.0.0)

Module mocking library for Erlang.

Summary

Types

Argument specification is used to specify argument patterns throughout Meck. In particular it is used in definition of expectation clauses by expect/3, expect/4, and by history digging functions num_called/3, called/3 to specify what arguments of a function call of interest should look like.

It is used in expect/3 and expect/4 to define a function clause of complex multi-clause expectations.

Represents a list of either successful function calls with a returned result or function calls that resulted in an exception with a type, reason and a stack trace. Each tuple begins with the pid of the process that made the call to the function.

Matcher is an entity that is used to check that a particular value meets some criteria. They are used in defining expectation where Erlang patterns are not enough. E.g. to check that a numeric value is within bounds. Instances of matcher can be created by is/1 function from either a predicate function or a hamcrest matcher. (see is/1 for details). An instance of this type may be specified in any or even all positions of an arg_spec().

Module, function and arguments that the mock module got called with.

Opaque data structure that specifies a value or a set of values to be returned by a mock stub function defined by either expect/3 and expect/4. Values of ret_spec() are constructed by seq/1, loop/1, val/1, exec/1, and raise/2 functions. They are used to specify return values in expect/3 and expect/4 functions, and also as a parameter of the stub_all option of new/2 function.

Erlang stack trace.

Functions

Returns whether Pid has called Mod:Func with Args.

Returns the value of an argument as it was passed to a particular function call made by a particular process. It fails with not_found error if a function call of interest has never been made.

Deletes an expectation.

Deletes an expectation.

Throws an expected exception inside an expect fun.

Creates a ret_spec() from a function. Calls to an expect, created with ret_spec() returned by this function, will be forwarded to the specified function.

Add expectation for a function Func to the mocked modules Mod.

Returns the list of expectations.

Returns the list of expectations.

Return the call history of the mocked module for the specified process.

creates a matcher/0 instance from either Predicate or HamcrestMatcher.

Converts a list of terms into ret_spec() defining a loop of values. It is intended to be in construction of clause specs for the expect/3 function.

Returns the currently mocked modules.

Equivalent to new(Mod, []).

Creates new mocked module(s).

Returns the number of times process Pid has called Mod:Func with Args.

Creates a ret_spec() that makes the original module function be called.

Calls the original function (if existing) inside an expectation fun.

Creates a ret_spec() that defines an exception.

Erases the call history for a mocked module or a list of mocked modules.

Converts a list of terms into ret_spec() defining a sequence of values. It is intended to be in construction of clause specs for the expect/3 function.

Unloads all mocked modules from memory.

Unload a mocked module or a list of mocked modules.

Converts a term into ret_spec() defining an individual value. It is intended to be in construction of clause specs for the expect/3 function.

Validate the state of the mock module(s).

Blocks until either function Mod:Func is called at least Times with arguments matching OptArgsSpec by process OptCallerPid, or Timeout has elapsed. In the latter case the call fails with error:timeout.

Types

-type args_spec() :: [any() | '_' | matcher()] | non_neg_integer().

Argument specification is used to specify argument patterns throughout Meck. In particular it is used in definition of expectation clauses by expect/3, expect/4, and by history digging functions num_called/3, called/3 to specify what arguments of a function call of interest should look like.

An argument specification can be given as a argument pattern list or as a non-negative integer that represents function clause/call arity.

If an argument specification is given as an argument pattern, then every pattern element corresponds to a function argument at the respective position. '_' is a wildcard that matches any value. In fact you can specify atom wildcard '_' at any level in the value structure. (E.g.: {1, [blah, {'_', "bar", 2} | '_'], 3}). It is also possible to use a matcher() created by is/1 in-place of a value pattern.

If an argument specification is given by an arity, then it is equivalent to a pattern based argument specification that consists solely of wildcards, and has the length of arity (e.g.: 3 is equivalent to ['_', '_', '_']).

-type func_clause_spec() :: {args_spec(), ret_spec()}.

It is used in expect/3 and expect/4 to define a function clause of complex multi-clause expectations.

-type history() ::
          [{CallerPid :: pid(), meck_mfa(), Result :: any()} |
           {CallerPid :: pid(),
            meck_mfa(),
            Class :: throw | error | exit,
            Reason :: any(),
            stack_trace()}].

Represents a list of either successful function calls with a returned result or function calls that resulted in an exception with a type, reason and a stack trace. Each tuple begins with the pid of the process that made the call to the function.

-opaque matcher()

Matcher is an entity that is used to check that a particular value meets some criteria. They are used in defining expectation where Erlang patterns are not enough. E.g. to check that a numeric value is within bounds. Instances of matcher can be created by is/1 function from either a predicate function or a hamcrest matcher. (see is/1 for details). An instance of this type may be specified in any or even all positions of an arg_spec().

-type meck_mfa() :: {Mod :: atom(), Func :: atom(), Args :: [any()]}.

Module, function and arguments that the mock module got called with.

-type ret_spec() :: meck_ret_spec:ret_spec().

Opaque data structure that specifies a value or a set of values to be returned by a mock stub function defined by either expect/3 and expect/4. Values of ret_spec() are constructed by seq/1, loop/1, val/1, exec/1, and raise/2 functions. They are used to specify return values in expect/3 and expect/4 functions, and also as a parameter of the stub_all option of new/2 function.

Note that any Erlang term X is a valid ret_spec() equivalent to meck:val(X).

-type stack_trace() ::
          [{Mod :: atom(), Func :: atom(), AriOrArgs :: byte() | [any()]} |
           {Mod :: atom(), Func :: atom(), AriOrArgs :: byte() | [any()], Location :: [{atom(), any()}]}].

Erlang stack trace.

Functions

Link to this function

called(Mod, OptFun, OptArgsSpec)

View Source
-spec called(Mod, OptFun, OptArgsSpec) -> boolean()
                when Mod :: atom(), OptFun :: '_' | atom(), OptArgsSpec :: '_' | args_spec().

Equivalent to called(Mod, Fun, Args, '_').

Returns whether Mod:Func has been called with Args.

Link to this function

called(Mod, OptFun, OptArgsSpec, OptCallerPid)

View Source
-spec called(Mod, OptFun, OptArgsSpec, OptCallerPid) -> boolean()
                when
                    Mod :: atom(),
                    OptFun :: '_' | atom(),
                    OptArgsSpec :: '_' | args_spec(),
                    OptCallerPid :: '_' | pid().

Returns whether Pid has called Mod:Func with Args.

This will check the history for the module, Mod, to determine whether process Pid call the function, Fun, with arguments, Args. If so, this function returns true, otherwise false.

Wildcards can be used, at any level in any term, by using the underscore atom: '_'

See also: called/3.

Link to this function

capture(Occur, Mod, Func, OptArgsSpec, ArgNum)

View Source
-spec capture(Occur, Mod, Func, OptArgsSpec, ArgNum) -> ArgValue
                 when
                     Occur :: first | last | pos_integer(),
                     Mod :: atom(),
                     Func :: atom(),
                     OptArgsSpec :: args_spec(),
                     ArgNum :: pos_integer(),
                     ArgValue :: any().

Equivalent to capture(Occur, Mod, Func, OptArgsSpec, ArgNum, '_').

Returns the value of an argument as it was passed to a particular function call, It fails with not_found error if a function call of interest has never been made.

It retrieves the value of argument at ArgNum position as it was passed to function call Mod:Func with arguments that match OptArgsSpec that occurred Occur'th according to the call history.

Atoms first and last can be used in place of the occurrence number to retrieve the argument value passed when the function was called the first or the last time respectively.

Link to this function

capture(Occur, Mod, Func, OptArgsSpec, ArgNum, OptCallerPid)

View Source
-spec capture(Occur, Mod, Func, OptArgsSpec, ArgNum, OptCallerPid) -> ArgValue
                 when
                     Occur :: first | last | pos_integer(),
                     Mod :: atom(),
                     Func :: atom(),
                     OptArgsSpec :: '_' | args_spec(),
                     ArgNum :: pos_integer(),
                     OptCallerPid :: '_' | pid(),
                     ArgValue :: any().

Returns the value of an argument as it was passed to a particular function call made by a particular process. It fails with not_found error if a function call of interest has never been made.

It retrieves the value of argument at ArgNum position as it was passed to function call Mod:Func with arguments that match OptArgsSpec made by process CallerPid that occurred Occur'th according to the call history.

Atoms first and last can be used in place of the occurrence number to retrieve the argument value passed when the function was called the first or the last time respectively.

If an occurrence of a function call irrespective of the calling process needs to be captured then _ might be passed as OptCallerPid, but it is better to use capture/5 instead.

-spec delete(Mods, Func, Ari) -> ok
                when Mods :: Mod | [Mod], Mod :: atom(), Func :: atom(), Ari :: byte().

Deletes an expectation.

Deletes the expectation for the function Func with the matching arity Arity. If the mock has passthrough enabled, this function restores the expectation to the original function. See delete/4.

Link to this function

delete(Mods, Func, Ari, Force)

View Source
-spec delete(Mods, Func, Ari, Force) -> ok
                when
                    Mods :: Mod | [Mod],
                    Mod :: atom(),
                    Func :: atom(),
                    Ari :: byte(),
                    Force :: boolean().

Deletes an expectation.

Deletes the expectation for the function Func with the matching arity Arity. Force is a flag to delete the function even if it is passthrough.

Link to this function

exception(Class, Reason)

View Source
-spec exception(Class, Reason) -> no_return() when Class :: throw | error | exit, Reason :: any().

Throws an expected exception inside an expect fun.

This exception will get thrown without invalidating the mocked module. That is, the code using the mocked module is expected to handle this exception.

Note: this code should only be used inside an expect fun.

-spec exec(fun()) -> ret_spec().

Creates a ret_spec() from a function. Calls to an expect, created with ret_spec() returned by this function, will be forwarded to the specified function.

Link to this function

expect(Mods, Func, Expectation)

View Source
-spec expect(Mods, Func, Expectation) -> ok
                when
                    Mods :: Mod | [Mod],
                    Mod :: atom(),
                    Func :: atom(),
                    Expectation :: function() | [func_clause_spec()].

Add expectation for a function Func to the mocked modules Mod.

An expectation is either of the following:

function()
a stub function that is executed whenever the function Func is called. The arity of function() identifies for which particular Func variant an expectation is created for (that is, a function with arity 2 will generate an expectation for Func/2).
[func_clause_spec()]
a list of arg_spec()/ret_spec() pairs. Whenever the function Func is called the arguments are matched against the arg_spec() in the list. As soon as the first match is found then a value defined by the corresponding ret_spec() is returned.

It affects the validation status of the mocked module(s). If an expectation is called with the wrong number of arguments or invalid arguments the mock module(s) is invalidated. It is also invalidated if an unexpected exception occurs.

Link to this function

expect(Mods, Func, ArgsSpec, RetSpec)

View Source
-spec expect(Mods, Func, ArgsSpec, RetSpec) -> ok
                when
                    Mods :: Mod | [Mod],
                    Mod :: atom(),
                    Func :: atom(),
                    ArgsSpec :: args_spec(),
                    RetSpec :: ret_spec().

Equivalent to expect(Mod, Func, [{ArgsSpec, RetSpec}]).

Adds an expectation with the supplied arity and return value.

This creates an expectation that has the only clause {ArgsSpec, RetSpec}.

-spec expects(Mods) -> [{Mod, Func, Ari}]
                 when Mods :: Mod | [Mod], Mod :: atom(), Func :: atom(), Ari :: byte().

Returns the list of expectations.

Returns the list of MFAs that were replaced by expectations

Link to this function

expects(Mods, ExcludePassthrough)

View Source
-spec expects(Mods, ExcludePassthrough) -> [{Mod, Func, Ari}]
                 when
                     Mods :: Mod | [Mod],
                     Mod :: atom(),
                     Func :: atom(),
                     Ari :: byte(),
                     ExcludePassthrough :: boolean().

Returns the list of expectations.

Returns the list of MFAs that were replaced by expectations If ExcludePassthrough is on, only expectations that are not direct passthroughs are returned

-spec history(Mod) -> history() when Mod :: atom().

Equivalent to history(Mod, '_').

Return the call history of the mocked module for all processes.

Link to this function

history(Mod, OptCallerPid)

View Source
-spec history(Mod, OptCallerPid) -> history() when Mod :: atom(), OptCallerPid :: '_' | pid().

Return the call history of the mocked module for the specified process.

Returns a list of calls to the mocked module and their results for the specified Pid. Results can be either normal Erlang terms or exceptions that occurred.

See also: called/3, called/4, history/1, num_calls/3, num_calls/4.

-spec is(MatcherImpl) -> matcher()
            when
                MatcherImpl :: Predicate | HamcrestMatcher,
                Predicate :: fun((any()) -> any()),
                HamcrestMatcher :: meck_matcher:hamcrest_matchspec().

creates a matcher/0 instance from either Predicate or HamcrestMatcher.

  • Predicate - is a single parameter function. If it returns true then the argument passed to it is considered as meeting the matcher criteria, otherwise as not.
  • HamcrestMatcher - is a matcher created by Hamcrest-Erlang library
-spec loop(Loop) -> ret_spec() when Loop :: [ret_spec()].

Converts a list of terms into ret_spec() defining a loop of values. It is intended to be in construction of clause specs for the expect/3 function.

Calls to an expect, created with ret_spec() returned by this function, will return one element at a time from the Loop list and will restart at the first element when the end is reached.

Link to this function

loop(Mods, Func, Ari, Loop)

View Source
This function is deprecated. Please use expect/3 or expect/4 along with ret_spec() generated by loop/1..
-spec loop(Mods, Func, Ari, Loop) -> ok
              when Mods :: Mod | [Mod], Mod :: atom(), Func :: atom(), Ari :: byte(), Loop :: [any()].

Equivalent to expect(Mod, Func, Ari, loop(Loop)).

-spec mocked() -> [atom()].

Returns the currently mocked modules.

-spec new(Mods) -> ok when Mods :: Mod | [Mod], Mod :: atom().

Equivalent to new(Mod, []).

-spec new(Mods, Options) -> ok
             when Mods :: Mod | [Mod], Mod :: atom(), Options :: [proplists:property()].

Creates new mocked module(s).

This replaces the current version (if any) of the modules in Mod with an empty module.

Since this library is intended to use from test code, this function links a process for each mock to the calling process.

The valid options are:

passthrough
Retains the original functions, if not mocked by meck. If used along with stub_all then stub_all is ignored.
no_link
Does not link the meck process to the caller process (needed for using meck in rpc calls).
unstick
Unstick the module to be mocked (e.g. needed for using meck with kernel and stdlib modules).
no_passthrough_cover
If cover is enabled on the module to be mocked then meck will continue to capture coverage on passthrough calls. This option allows you to disable that feature if it causes problems.
{spawn_opt, list()}
Specify Erlang process spawn options. Typically used to specify non-default, garbage collection options.
no_history
Do not store history of meck calls.
non_strict
A mock created with this option will allow setting expectations on functions that does not exist in the mocked module. With this option on it is even possible to mock non existing modules.
{stub_all,ret_spec()}
Stubs all functions exported from the mocked module. The stubs will return whatever defined by ret_spec() regardless of arguments passed in. It is possible to specify this option as just stub_all then stubs will return atom ok. If used along with passthrough then stub_all is ignored.
merge_expects
The expectations for the function/arity signature are merged with existing ones instead of replacing all of them each time an expectation is added. Expectations are added to the end of the function clause list, meaning that pattern matching will be performed in the order the expectations were added.

Possible exceptions:

error:{undefined_module, Mod}
The module to be mocked does not exist. This error exists to prevent mocking of misspelled module names. To bypass this and create a new mocked module anyway, use the option non_strict.
error:{module_is_sticky, Mod}
The module to be mocked resides in a sticky directory. To unstick the module and mock it anyway, use the option unstick.
error:{abstract_code_not_found, Mod}
The option passthrough was used but the original module has no abstract code which can be called. Make sure the module is compiled with the compiler option debug_info.
Link to this function

num_calls(Mod, OptFun, OptArgsSpec)

View Source
-spec num_calls(Mod, OptFun, OptArgsSpec) -> non_neg_integer()
                   when Mod :: atom(), OptFun :: '_' | atom(), OptArgsSpec :: '_' | args_spec().

Equivalent to num_calls(Mod, Fun, Args, '_').

Returns the number of times Mod:Func has been called with Args.

Link to this function

num_calls(Mod, OptFun, OptArgsSpec, OptCallerPid)

View Source
-spec num_calls(Mod, OptFun, OptArgsSpec, OptCallerPid) -> non_neg_integer()
                   when
                       Mod :: atom(),
                       OptFun :: '_' | atom(),
                       OptArgsSpec :: '_' | args_spec(),
                       OptCallerPid :: '_' | pid().

Returns the number of times process Pid has called Mod:Func with Args.

This will check the history for the module, Mod, to determine how many times process Pid has called the function, Fun, with arguments, Args and returns the result.

See also: num_calls/3.

-spec passthrough() -> ret_spec().

Creates a ret_spec() that makes the original module function be called.

Calls to an expect, created with ret_spec() returned by this function, will be forwarded to the original function.

-spec passthrough(Args) -> Result when Args :: [any()], Result :: any().

Calls the original function (if existing) inside an expectation fun.

Note: this code should only be used inside an expect fun.

-spec raise(Class, Reason) -> ret_spec() when Class :: throw | error | exit, Reason :: term().

Creates a ret_spec() that defines an exception.

Calls to an expect, created with ret_spec() returned by this function, will raise the specified exception.

-spec reset(Mods) -> ok when Mods :: Mod | [Mod], Mod :: atom().

Erases the call history for a mocked module or a list of mocked modules.

This function will erase all calls made heretofore from the history of the specified modules. It is intended to prevent cluttering of test results with calls to mocked modules made during the test setup phase.

-spec seq(Sequence) -> ret_spec() when Sequence :: [ret_spec()].

Converts a list of terms into ret_spec() defining a sequence of values. It is intended to be in construction of clause specs for the expect/3 function.

Calls to an expect, created with ret_spec returned by this function, will exhaust the Sequence list of return values in order until the last value is reached. That value is then returned for all subsequent calls.

Link to this function

sequence(Mods, Func, Ari, Sequence)

View Source
This function is deprecated. Please use expect/3 or expect/4 along with ret_spec() generated by seq/1..
-spec sequence(Mods, Func, Ari, Sequence) -> ok
                  when
                      Mods :: Mod | [Mod],
                      Mod :: atom(),
                      Func :: atom(),
                      Ari :: byte(),
                      Sequence :: [any()].

Equivalent to expect(Mod, Func, Ari, seq(Sequence)).

-spec unload() -> Unloaded when Unloaded :: [Mod], Mod :: atom().

Unloads all mocked modules from memory.

The function returns the list of mocked modules that were unloaded in the process.

-spec unload(Mods) -> ok when Mods :: Mod | [Mod], Mod :: atom().

Unload a mocked module or a list of mocked modules.

This will purge and delete the module(s) from the Erlang virtual machine. If the mocked module(s) replaced an existing module, this module will still be in the Erlang load path and can be loaded manually or when called.

-spec val(Value) -> ret_spec() when Value :: any().

Converts a term into ret_spec() defining an individual value. It is intended to be in construction of clause specs for the expect/3 function.

-spec validate(Mods) -> boolean() when Mods :: Mod | [Mod], Mod :: atom().

Validate the state of the mock module(s).

The function returns true if the mocked module(s) has been used according to its expectations. It returns false if a call has failed in some way. Reasons for failure are wrong number of arguments or non-existing function (undef), wrong arguments (function clause) or unexpected exceptions.

Validation can detect:

  • When a function was called with the wrong argument types (function_clause)
  • When an exception was thrown
  • When an exception was thrown and expected (via meck:exception/2), which still results in true being returned

Validation cannot detect:

  • When you didn't call a function
  • When you called a function with the wrong number of arguments (undef)
  • When you called an undefined function (undef)

The reason Meck cannot detect these cases is because of how it is implemented. Meck replaces the module with a mock and a process that maintains the mock. Everything Meck get goes through that mock module. Meck does not insert itself at the caller level (i.e. in your module or in your test case), so it cannot know that you failed to call a module.

Use the history/1 or history/2 function to analyze errors.

Link to this function

wait(Mod, OptFunc, OptArgsSpec, Timeout)

View Source
-spec wait(Mod, OptFunc, OptArgsSpec, Timeout) -> ok
              when
                  Mod :: atom(),
                  OptFunc :: '_' | atom(),
                  OptArgsSpec :: '_' | args_spec(),
                  Timeout :: non_neg_integer().

Equivalent to wait(1, Mod, OptFunc, OptArgsSpec, '_', Timeout).

Blocks until either function Mod:Func is called at least once with arguments matching OptArgsSpec, or Timeout has elapsed. In the latter case the call fails with error:timeout.

The number of calls is counted starting from the most resent call to reset/1 on the mock or from the mock creation, whichever occurred latter. If a matching call has already occurred, then the function returns ok immediately.

Link to this function

wait(Times, Mod, OptFunc, OptArgsSpec, Timeout)

View Source
-spec wait(Times, Mod, OptFunc, OptArgsSpec, Timeout) -> ok
              when
                  Times :: pos_integer(),
                  Mod :: atom(),
                  OptFunc :: '_' | atom(),
                  OptArgsSpec :: '_' | args_spec(),
                  Timeout :: non_neg_integer().

Equivalent to wait(Times, Mod, OptFunc, OptArgsSpec, '_', Timeout).

Blocks until either function Mod:Func is called at least Times with arguments matching OptArgsSpec, or Timeout has elapsed. In the latter case the call fails with error:timeout.

The number of calls is counted starting from the most resent call to reset/1 on the mock or from the mock creation, whichever occurred latter. If Times number of matching calls has already occurred, then the function returns ok immediately.

Link to this function

wait(Times, Mod, OptFunc, OptArgsSpec, OptCallerPid, Timeout)

View Source
-spec wait(Times, Mod, OptFunc, OptArgsSpec, OptCallerPid, Timeout) -> ok
              when
                  Times :: pos_integer(),
                  Mod :: atom(),
                  OptFunc :: '_' | atom(),
                  OptArgsSpec :: '_' | args_spec(),
                  OptCallerPid :: '_' | pid(),
                  Timeout :: non_neg_integer().

Blocks until either function Mod:Func is called at least Times with arguments matching OptArgsSpec by process OptCallerPid, or Timeout has elapsed. In the latter case the call fails with error:timeout.

The number of calls is counted starting from the most resent call to reset/1 on the mock or from the mock creation, whichever occurred latter. If Times number of matching call has already occurred, then the function returns ok immediately.