Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Add overview.edoc
  • Loading branch information
Sven Heyll committed Dec 11, 2012
1 parent 84328bc commit 7447996
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 175 deletions.
153 changes: 153 additions & 0 deletions doc/overview.edoc
@@ -0,0 +1,153 @@
@author Sven Heyll <sven.heyll@gmail.com>
@copyright 2011, 2012 Sven Heyll
@version 4
@title ErlyMock - An EasyMock inspired mocking library.
@doc

<p> ErlyMock was built to be helpful for Test Driven Development. I know this
goal is by no means yet reached, so I ask you kindly to support this
project. All suggestions, complaints and improvements are welcome. </p>

<p>
ErlyMock is the latest incarnation of an Erlang mocking library inspired by
Easymock for Java. It is used in unit tests to verify that a set of functions is
called by the code under test in correct order and with correct parameters.
</p>
<p>
With ErlyMock it is possible to declare the behavior of arbitrary
modules/functions with or without expecting acutal invocations. The user simply
declares what each function call to some function should return or do at the
beginning of a unit test.
</p>
<h2>Some features:</h2>
<ul>
<li>API documentation</li>
<li>battle proven in at least three large projects at http://www.lindenbaum.eu</li>
<li>comprehensive runtime messages</li>
<li>two-letter module name(we went from 'mock' to 'em', which was quite an improvement for us)</li>
<li>small, flexible and easy to use API</li>
<li>allows strict expectations</li>
<li>allows stub behavior definitions to be intuitively mixed with strict expectations</li>
<li>correctly restores cover compiled module</li>
<li>automatic cleanup when mock or test process dies</li>
<li>implemented with OTP standard behaviour</li>
<li>rebar enabled</li></ul>

<h2>Usage example:</h2>

<p>Assume there are two modules, used by the code to be tested, that shall be mocked (at least to prevent damaging side effects):</p>

A rocket launcher server:
<code>
-module(rocket_launcher).

launch(Longitude, Latitude, Type) ->
....
</code>
And A UI module:
<code>
-module(rocket_launcher_ui).

ask_for_instructions() ->
...
</code>
Then this is how a happy case unit test might look like:
<code>
launche_missle_test() ->
% create a new mock process
M = em:new(),

% define the expectations
em:strict(M, rocket_launcher_ui, ask_for_instructions, [],
{return, [{longitude, 123},
{latitude, 999},
{type, some_rocket_type}]}),
em:strict(M, missle_lauchner, launch, [123, 999, some_rocket_type]),

% tell the mock that all expectations are defined
em:replay(M),

% run code under test
rocket_app:interactive(),

% verify expectations immediately
em:verify(M).
</code>

Another example shall show the usefulness of {@link em:await_expectations/1}
instead of {@link em:verify/1} to wait for asynchronouse invokations and {@link
em:zelf/1} as argument matcher matching the process id of the process calling
the mocked functions in the replay phase.

<code>

%% Let's look at the impl first:
-module(xxx_impl).



download_image(Url) ->
gen_server:cast(?MODULE, {download, URL}).

%% ...

handle_cast({download, URL}, State) ->
net_io:schedule_download(Url, self()),
{noreply, State}.

%%%%%%%%%% Now this 'cast' happens asynchronously using 'em:verify/1' would not
%%%%%%%%%% help a lot, it would be pure luck if the erlang scheduler executed
%%%%%%%%%% that handle_cast before. This is the case where
%%%%%%%%%% em:await_expectations/1 comes in handy...

%% Let's look at the test first:

downld_img_test() ->
% create a new mock process
M = em:new(),

Url = test_url,

em:strict(M, net_io, schedule_download,
[Url,
%% em:zelf() will match 'self()' of the process under test!
em:zelf()]),

em:replay(M),

%% call code under test
xxx_impl:download_image(Url),

%% await the cast to happen:
em:await_expectations(M).

</code>

<strong>For more details please read the {@link em} module documentation.</strong>


<h2>History</h2>

<p> ErlyMock has undergone many stages and years of development and usage before
reaching this stage.</p>

<p> It was first published here:
http://sheyll.blogspot.com/2009/02/erlang-mock-erlymock.html Then Samual Rivas
cleaned it up and added support for restoring cover compiled modules for his
project, see http://www.lambdastream.com/. </p>

<p>The code was then added with all modifications to the great new
erlang-maven-plugin forge which can be found here:
http://sourceforge.net/projects/erlang-plugin/. </p>

<p> Then I decided to partially rewrite ErlyMock in order to provide a simpler
API and in order to improve the code quality. Also, I wanted to use the gen_fsm
OTP standard behavior.</p>

<p> Later loxybjorn on github added rebar support, now erlymock could automatically be added to rebar projects.</p>

<p> Several improvements were added by Olle Törnström, who helped fixing module purging issues.</p>

<p> Finally I decided to remove maven support, and to rely totally on rebar.</p>

<strong>Thanks to all who helped with erlymock.</strong>
9 changes: 0 additions & 9 deletions src/changes/changes.xml

This file was deleted.

150 changes: 0 additions & 150 deletions src/site/apt/index.apt.vm

This file was deleted.

16 changes: 0 additions & 16 deletions src/site/site.xml

This file was deleted.

0 comments on commit 7447996

Please sign in to comment.