Skip to content
Permalink
Browse files
Refresh README
  • Loading branch information
eproxus committed Feb 2, 2017
1 parent 6f1281d commit 2fcbfb1f6c70d2e4affeb4b1a887899c1c3379d3
Showing 1 changed file with 81 additions and 69 deletions.
150 README.md
@@ -1,6 +1,8 @@
[![Release](http://img.shields.io/github/release/eproxus/meck.svg?style=flat-square)](https://github.com/eproxus/meck/releases/latest)
[![Build Status](https://img.shields.io/travis/eproxus/meck/master.svg?style=flat-square)](http://travis-ci.org/eproxus/meck)
[![Code Climate](http://img.shields.io/badge/code_climate-Erlang_18.3-brightgreen.svg?style=flat-square)](https://travis-ci.org/eproxus/meck/branches)
[![Travis][travis badge]][travis]
[![Hex.pm Version][hex version badge]][hex]
[![Hex.pm License][hex license badge]][hex]
[![Erlang Versions][erlang version badge]][travis]
[![Build Tool][build tool]][hex]

Meck
====
@@ -10,7 +12,7 @@ A mocking library for Erlang.
Features
--------

See what's new in [0.8 Release Notes][1].
See what's new in [0.8 Release Notes][release_notes_0.8].

* Dynamic return values using sequences and loops of static values
* Compact definition of mock arguments, clauses and return values
@@ -20,7 +22,7 @@ See what's new in [0.8 Release Notes][1].
* Throwing of expected exceptions that keeps the module valid
* Throws an error when mocking a module that doesn't exist or has been
renamed (disable with option `non_strict`)
* Support for [Hamcrest][2] matchers
* Support for [Hamcrest][hamcrest] matchers
* Automatic backup and restore of cover data
* Mock is linked to the creating process and will unload automatically
when a crash occurs (disable with option `no_link`)
@@ -46,9 +48,9 @@ ok
** exception error: undefined function dog:bark/0
```

Exceptions can be anticipated by Meck (resulting in validation still
passing). This is intended to be used to test code that can and should
handle certain exceptions indeed does take care of them:
Exceptions can be anticipated by Meck (resulting in validation still passing).
This is intended to be used to test code that can and should handle certain
exceptions indeed does take care of them:

```erl
5> meck:expect(dog, meow, fun() -> meck:exception(error, not_a_cat) end).
@@ -66,10 +68,10 @@ ok
true
```

Normal Erlang exceptions result in a failed validation. The following
example is just to demonstrate the behavior, in real test code the
exception would normally come from the code under test (which should,
if not expected, invalidate the mocked module):
Normal Erlang exceptions result in a failed validation. The following example is
just to demonstrate the behavior, in real test code the exception would normally
come from the code under test (which should, if not expected, invalidate the
mocked module):

```erl
8> meck:expect(dog, jump, fun(Height) when Height > 3 ->
@@ -103,11 +105,10 @@ my_test() ->
meck:unload(my_library_module).
```

Pass-through is used when the original functionality of a module
should be kept. When the option `passthrough` is used when calling
`new/2` all functions in the original module will be kept in the
mock. These can later be overridden by calling `expect/3` or
`expect/4`.
Pass-through is used when the original functionality of a module should be kept.
When the option `passthrough` is used when calling `new/2` all functions in the
original module will be kept in the mock. These can later be overridden by
calling `expect/3` or `expect/4`.

```erl
Eshell V5.8.4 (abort with ^G)
@@ -117,11 +118,10 @@ ok
"test"
```

It's also possible to pass calls to the original function allowing us
to override only a certain behavior of a function (this usage is
compatible with the `passthrough` option). `passthrough/1` will always
call the original function with the same name as the expect is
defined in):
It's also possible to pass calls to the original function allowing us to
override only a certain behavior of a function (this usage is compatible with
the `passthrough` option). `passthrough/1` will always call the original
function with the same name as the expect is defined in):

```erl
Eshell V5.8.4 (abort with ^G)
@@ -137,17 +137,31 @@ ok
"test"
```

Use
---

Meck is best used via [Rebar 3]. Add the following dependency to your
`rebar.config` in your project root:

```erlang
{deps, [
{meck, "0.8.4"}
]}.
```

Build
-----

Meck requires `make` and [rebar][1] to build. To build Meck go to the Meck directory
Meck requires `make` and [Rebar 2][rebar_2] to build (included in the
repository, to be upgraded to Rebar 3). To build Meck go to the Meck directory
and simply type:

```sh
make
```

In order to run all tests for Meck type the following command from the same directory:
In order to run all tests for Meck type the following command from the same
directory:

```sh
make test
@@ -158,53 +172,36 @@ Two things might seem alarming when running the tests:
1. Warnings emitted by cover
2. An exception printed by SASL

Both are expected due to the way Erlang currently prints errors. The
important line you should look for is `All XX tests passed`, if that
appears all is correct.
Both are expected due to the way Erlang currently prints errors. The important
line you should look for is `All XX tests passed`, if that appears all is
correct.

Documentation can be generated through the use of the following command:

```sh
make doc
```

Install
-------

Meck is best used via [rebar][3]. Add the following dependency t
your `rebar.config` in your project root:

```erlang
{deps, [
{meck, ".*",
{git, "https://github.com/eproxus/meck.git", {tag, "0.8.3"}}}
]}.
```

If you want to install your own built version of Meck add the ebin
directory to your Erlang code path or move the Meck folder into your
release folder and make sure that folder is in your `ERL_LIBS`
environment variable.

Caveats
-------

Meck will have trouble mocking certain modules since Meck works by
recompiling and reloading modules. Since Erlang have a flat module
namespace, replacing a module has to be done globally in the
Erlang VM. This means certain modules cannot be mocked. The
following is a non-exhaustive list of modules that can either be
problematic to mock or not possible at all:
Meck will have trouble mocking certain modules since Meck works by recompiling
and reloading modules. Since Erlang have a flat module namespace, replacing a
module has to be done globally in the Erlang VM. This means certain modules
cannot be mocked. The following is a non-exhaustive list of modules that can
either be problematic to mock or not possible at all:

* `erlang`
* `os`
* `crypto`
* `compile`
* `global`
* `timer` (possible to mock, but used by some test frameworks, like Elixir's ExUnit)
* `timer` (possible to mock, but used by some test frameworks, like Elixir's
ExUnit)

Also, a meck expectation set up for a function _f_ does not apply to the module-
local invocation of _f_ within the mocked module. Consider the following module:

Also, a meck expectation set up for a function _f_ does not apply to the module-local invocation of _f_ within the mocked module.
Consider the following module:
```
-module(test).
-export([a/0, b/0, c/0]).
@@ -218,7 +215,9 @@ b() ->
c() ->
original.
```
Note how the module-local call to `c/0` in `a/0` stays unchanged even though the expectation changes the externally visible behaviour of `c/0`:

Note how the module-local call to `c/0` in `a/0` stays unchanged even though the
expectation changes the externally visible behaviour of `c/0`:

```
3> meck:new(test, [passthrough]).
@@ -236,24 +235,37 @@ changed
Contribute
----------

Patches are greatly appreciated! For a much nicer history, please
[write good commit messages][5]. Use a branch name prefixed by
`feature/` (e.g. `feature/my_example_branch`) for easier integration
when developing new features or fixes for meck.
Patches are greatly appreciated! For a much nicer history, please [write good
commit messages][commit_messages]. Use a branch name prefixed by `feature/`
(e.g. `feature/my_example_branch`) for easier integration when developing new
features or fixes for meck.

Should you find yourself using Meck and have issues, comments or
feedback please [create an issue here on GitHub][4].
Should you find yourself using Meck and have issues, comments or feedback please
[create an issue here on GitHub][issues].

Meck has been greatly improved by [many contributors]
(https://github.com/eproxus/meck/graphs/contributors)!

### Donations

If you or your company use Meck and find it useful, Bitcoin donations to the address `1M7pLbBpjkwxffT7kZPKhxiPGKf4eHDqtz` are greatly appreciated!

[1]: https://github.com/eproxus/meck/wiki/0.8-Release-Notes
"0.8 Release Notes"
[2]: https://github.com/hyperthunk/hamcrest-erlang "Hamcrest for Erlang"
[3]: https://github.com/basho/rebar "Rebar - A build tool for Erlang"
[4]: http://github.com/eproxus/meck/issues "Meck issues"

If you or your company use Meck and find it useful, [Bitcoin
donations][coinbase] are greatly appreciated!


<!-- Badges -->
[travis]: https://travis-ci.org/eproxus/meck
[travis badge]: https://img.shields.io/travis/eproxus/meck.svg?style=flat-square
[hex]: https://hex.pm/packages/meck
[hex version badge]: https://img.shields.io/hexpm/v/meck.svg?style=flat-square
[hex license badge]: https://img.shields.io/hexpm/l/meck.svg?style=flat-square
[erlang version badge]: https://img.shields.io/badge/erlang-R15B03%20to%2019.2-blue.svg?style=flat-square
[build tool]: https://img.shields.io/badge/build%20tool-rebar3-orange.svg?style=flat-square

<!-- Links -->
[release_notes_0.8]: https://github.com/eproxus/meck/wiki/0.8-Release-Notes
[hamcrest]: https://github.com/hyperthunk/hamcrest-erlang
[rebar_2]: https://github.com/rebar/rebar
[rebar_3]: https://github.com/erlang/rebar3
[issues]: http://github.com/eproxus/meck/issues
[commit_messages]: http://chris.beams.io/posts/git-commit/
[coinbase]: https://www.coinbase.com/alind

0 comments on commit 2fcbfb1

Please sign in to comment.