erlangeunitmeck

Correct way to use meck with foreach


I am using meck to test my gen_server mymodule. In particular I use meck to mock httpc following the instructions provided here.

Here is some code I extracted from my test:

do_some_tests_() ->
  {foreach,
   fun start/0,
   fun stop/1,
   [fun do_some_stuff/1,
    fun do_some_other_stuff/1
   ]}.

start() ->
  {ok, _} = mymodule:start_link(),
  meck:new(httpc),
  _Pid = self().

stop(_) ->
  meck:unload(httpc), 
  mymodule:stop().

do_some_stuff(Pid) ->
  %% here i use meck
  meck:expect(httpc, request, 
    fun(post, {_URL, _Header, ContentType, Body}, [], []) ->
        Reply = "Data to send back"
        Pid ! {ok, {{"", 200, ""}, [], Reply}}
    end),
  %% here i do the post request
  mymodule:myfunction(Body),
  receive 
    Any -> 
      [
       ?_assertMatch({ok, {{_, 200, _}, [], _}}, Any), 
       ?_assert(meck:validate(httpc))
      ]
  end.

With this code I am able to get the tests running but there are still two things I can't understand:

1) In the results I get something like:

mymodule_test:43: do_some_stuff...ok
mymodule_test:43: do_some_stuff...ok
mymodule_test:53: do_some_other_stuff...ok
mymodule_test:53: do_some_other_stuff...ok

Is it possible to get only one line for each test instead of two?

2) How can I add a speaking description for each test?


Solution

  • The function do_some_stuff(Pid) generates two tests, so it's pretty normal both are checked and displayed.

    You can however add a name/description to each generator & test:

    do_some_tests_() -> 
      {foreach,
      fun start/0,
      fun stop/1,
      [{"Doing some stuff" , fun do_some_stuff/1},
       {"Doing some other stuff" , fun do_some_other_stuff/1}
      ]}.
    
    
    
    
    do_some_stuff(Pid) ->
      %% [code]
      [
       {"Check 200" , ?_assertMatch({ok, {{_, 200, _}, [], _}}, Any)}, 
       {"Check httpc" , ?_assert(meck:validate(httpc))}
      ]
      end.
    

    This should display something in the likes of:

    module 'MyModule'
      Doing Some Stuff
        module:57: do_some_stuff (Check 200)...ok
        module:58: do_some_stuff (Check httpc)...ok
    

    In EUnit parlance, these are know as "titles":

    Titles

    Any test or test set T can be annotated with a title, by wrapping it in a pair {Title, T}, where Title is a string. For convenience, any test which is normally represented using a tuple can simply be given a title string as the first element, i.e., writing {"The Title", ...} instead of adding an extra tuple wrapper as in {"The Title", {...}}.

    http://www.erlang.org/doc/apps/eunit/chapter.html#id61107